Improved network
This commit is contained in:
parent
600ecd5406
commit
5206469764
@ -53,8 +53,8 @@
|
|||||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/Vector2IntTest.cs" />
|
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/Vector2IntTest.cs" />
|
||||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Quaternion.cs" />
|
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Quaternion.cs" />
|
||||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/float16.cs" />
|
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/float16.cs" />
|
||||||
<Compile Include="Assets/NanoBrain/VisualEditor/NanoBrainObj.cs" />
|
|
||||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/DirectionTest.cs" />
|
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/DirectionTest.cs" />
|
||||||
|
<Compile Include="Assets/NanoBrain/VisualEditor/NanoBrain.cs" />
|
||||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/Vector2FloatTest.cs" />
|
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/Vector2FloatTest.cs" />
|
||||||
<Compile Include="Assets/Scenes/Boids/Scripts/SwarmSpawner.cs" />
|
<Compile Include="Assets/Scenes/Boids/Scripts/SwarmSpawner.cs" />
|
||||||
<Compile Include="Assets/NanoBrain/Perceptoid.cs" />
|
<Compile Include="Assets/NanoBrain/Perceptoid.cs" />
|
||||||
@ -62,6 +62,7 @@
|
|||||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Vector2Float.cs" />
|
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Vector2Float.cs" />
|
||||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/SwingTwistTest.cs" />
|
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/SwingTwistTest.cs" />
|
||||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Vector3Int.cs" />
|
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Vector3Int.cs" />
|
||||||
|
<Compile Include="Assets/NanoBrain/PercepteiArray.cs" />
|
||||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Vector3Float.cs" />
|
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Vector3Float.cs" />
|
||||||
<Compile Include="Assets/NanoBrain/Receptor.cs" />
|
<Compile Include="Assets/NanoBrain/Receptor.cs" />
|
||||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Matrix.cs" />
|
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Matrix.cs" />
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using LinearAlgebra;
|
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class Neuroid : Nucleus {
|
public class Neuroid : Nucleus {
|
||||||
@ -80,11 +78,9 @@ public class Neuroid : Nucleus {
|
|||||||
|
|
||||||
//Applying the weight factgors
|
//Applying the weight factgors
|
||||||
foreach (Synapse synapse in this.synapses) {
|
foreach (Synapse synapse in this.synapses) {
|
||||||
Vector3 outputValue = synapse.nucleus.outputValue;
|
sum += synapse.weight * synapse.nucleus.outputValue;
|
||||||
float magnitude = synapse.weight * outputValue.magnitude;
|
if (synapse.nucleus.outputValue.sqrMagnitude != 0)
|
||||||
|
n++;
|
||||||
sum += magnitude * outputValue.normalized;
|
|
||||||
n++;
|
|
||||||
}
|
}
|
||||||
if (average)
|
if (average)
|
||||||
sum /= n;
|
sum /= n;
|
||||||
|
|||||||
@ -154,11 +154,11 @@ public class Nucleus {
|
|||||||
public virtual void UpdateState() { }
|
public virtual void UpdateState() { }
|
||||||
|
|
||||||
public void UpdateResult(Vector3 result) {
|
public void UpdateResult(Vector3 result) {
|
||||||
float d = Vector3.Distance(result, this.outputValue);
|
// float d = Vector3.Distance(result, this.outputValue);
|
||||||
if (d < 0.5f) {
|
// if (d < 0.5f) {
|
||||||
//Debug.Log($"insignificant update: {d}");
|
// //Debug.Log($"insignificant update: {d}");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
this.outputValue = result;
|
this.outputValue = result;
|
||||||
foreach (Receiver receiver in this.receivers)
|
foreach (Receiver receiver in this.receivers)
|
||||||
|
|||||||
22
Assets/NanoBrain/PercepteiArray.cs
Normal file
22
Assets/NanoBrain/PercepteiArray.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
public class PercepteiArray {
|
||||||
|
public ArrayPerceptoid[] perceptei;
|
||||||
|
public string name;
|
||||||
|
|
||||||
|
public PercepteiArray(NanoBrain brain, int thingType, string baseName, uint count) {
|
||||||
|
this.name = baseName;
|
||||||
|
this.perceptei = new ArrayPerceptoid[count];
|
||||||
|
for (uint i = 0; i < count; i++) {
|
||||||
|
this.perceptei[i] = new ArrayPerceptoid(brain, thingType, $"{baseName}[{i}]") {
|
||||||
|
array = this
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ArrayPerceptoid : Perceptoid {
|
||||||
|
public PercepteiArray array;
|
||||||
|
|
||||||
|
public ArrayPerceptoid(NanoBrain brain, int thingType, string name = "sensor") : base(brain, thingType, name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
2
Assets/NanoBrain/PercepteiArray.cs.meta
Normal file
2
Assets/NanoBrain/PercepteiArray.cs.meta
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f8cac60bd79854595a8571c042f77998
|
||||||
@ -6,7 +6,7 @@ public class Perceptoid : Neuroid {
|
|||||||
// A neuroid which has no neurons as input
|
// A neuroid which has no neurons as input
|
||||||
// But receives value from a receptor
|
// But receives value from a receptor
|
||||||
public Receptor receptor;
|
public Receptor receptor;
|
||||||
//public VelocityNeuroid velocityNeuroid;
|
public string baseName;
|
||||||
|
|
||||||
#region Serialization
|
#region Serialization
|
||||||
|
|
||||||
@ -58,21 +58,22 @@ public class Perceptoid : Neuroid {
|
|||||||
|
|
||||||
this.nucleusType = nameof(Perceptoid);
|
this.nucleusType = nameof(Perceptoid);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.baseName = name;
|
||||||
this.thingType = thingType;
|
this.thingType = thingType;
|
||||||
this.receptor = Receptor.GetReceptor(brain, thingType);
|
this.receptor = Receptor.GetReceptor(brain, thingType);
|
||||||
this.receptor.perceptei.Add(this);
|
this.receptor.perceptei.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Replace(int thingType, string name = "sensor") {
|
// public void Replace(int thingType, string name = "sensor") {
|
||||||
this.name = name;
|
// this.name = name;
|
||||||
|
|
||||||
this.thingType = thingType;
|
// this.thingType = thingType;
|
||||||
this.receptor.thingType = thingType;
|
// this.receptor.thingType = thingType;
|
||||||
this.receptor.localPosition = Vector3.zero;
|
// this.receptor.localPosition = Vector3.zero;
|
||||||
|
|
||||||
this.outputValue = Vector3.zero;
|
// this.outputValue = Vector3.zero;
|
||||||
this.receivers = new();
|
// this.receivers = new();
|
||||||
}
|
// }
|
||||||
|
|
||||||
public override void UpdateState() {
|
public override void UpdateState() {
|
||||||
Vector3 result = this.receptor.localPosition;
|
Vector3 result = this.receptor.localPosition;
|
||||||
@ -80,11 +81,11 @@ public class Perceptoid : Neuroid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Perceptoid GetPerception(NanoBrain brain, int thingType = 0) {
|
// public static Perceptoid GetPerception(NanoBrain brain, int thingType = 0) {
|
||||||
foreach (Nucleus nucleus in brain.nuclei) {
|
// foreach (Nucleus nucleus in brain.nuclei) {
|
||||||
if (nucleus is Perceptoid perceptoid && (thingType == 0 || perceptoid.receptor.thingType == thingType))
|
// if (nucleus is Perceptoid perceptoid && (thingType == 0 || perceptoid.receptor.thingType == thingType))
|
||||||
return perceptoid;
|
// return perceptoid;
|
||||||
}
|
// }
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@ public class Receptor {
|
|||||||
return newReceptor;
|
return newReceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ProcessStimulus(int thingId, Vector3 newLocalPositionVector) {
|
public virtual void ProcessStimulus(int thingId, Vector3 newLocalPositionVector, string thingName = null) {
|
||||||
this.localPosition = newLocalPositionVector;
|
this.localPosition = newLocalPositionVector;
|
||||||
|
|
||||||
Perceptoid selectedPerceptoid = null;
|
Perceptoid selectedPerceptoid = null;
|
||||||
@ -75,6 +75,8 @@ public class Receptor {
|
|||||||
}
|
}
|
||||||
// Debug.Log($"Stimulus {thingType} {thingId} {selectedPerceptoid.name}");
|
// Debug.Log($"Stimulus {thingType} {thingId} {selectedPerceptoid.name}");
|
||||||
selectedPerceptoid.thingId = thingId;
|
selectedPerceptoid.thingId = thingId;
|
||||||
|
if (thingName != null)
|
||||||
|
selectedPerceptoid.name = selectedPerceptoid.baseName + " " + thingName;
|
||||||
selectedPerceptoid.UpdateState();
|
selectedPerceptoid.UpdateState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
/*
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UIElements;
|
using UnityEngine.UIElements;
|
||||||
@ -406,7 +407,7 @@ public class GraphBoardView : VisualElement {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
public class NodeView : VisualElement {
|
public class NodeView : VisualElement {
|
||||||
Nucleus data;
|
Nucleus data;
|
||||||
GraphBoardView board;
|
GraphBoardView board;
|
||||||
@ -466,7 +467,7 @@ public class NodeView : VisualElement {
|
|||||||
//dragging = false;
|
//dragging = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
public class GraphNodeWrapper : ScriptableObject {
|
public class GraphNodeWrapper : ScriptableObject {
|
||||||
// expose fields that map to GraphNode
|
// expose fields that map to GraphNode
|
||||||
@ -507,3 +508,4 @@ public static class OpenAssetHandler {
|
|||||||
return false; // let Unity open normally
|
return false; // let Unity open normally
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
@ -181,22 +181,6 @@ public class NanoBrainInspector : Editor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// basic pan/zoom handling
|
|
||||||
// void OnWheel(WheelEvent e) {
|
|
||||||
// if (e.ctrlKey) {
|
|
||||||
// float delta = -e.delta.y * 0.001f;
|
|
||||||
// zoom = Mathf.Clamp(zoom + delta, 0.25f, 2f);
|
|
||||||
// content.transform.rotation = Quaternion.identity; // keep transform accessible
|
|
||||||
// content.transform.scale = new Vector3(zoom, zoom, 1);
|
|
||||||
// e.StopPropagation();
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// pan += e.delta;
|
|
||||||
// content.style.left = pan.x;
|
|
||||||
// content.style.top = pan.y;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
void OnMouseDown(MouseDownEvent e) {
|
void OnMouseDown(MouseDownEvent e) {
|
||||||
if (e.button == 2) { draggingCanvas = true; lastMouse = e.mousePosition; e.StopPropagation(); }
|
if (e.button == 2) { draggingCanvas = true; lastMouse = e.mousePosition; e.StopPropagation(); }
|
||||||
}
|
}
|
||||||
@ -220,8 +204,6 @@ public class NanoBrainInspector : Editor {
|
|||||||
|
|
||||||
Handles.BeginGUI();
|
Handles.BeginGUI();
|
||||||
DrawGraph();
|
DrawGraph();
|
||||||
// foreach (NeuroidLayer layer in layers)
|
|
||||||
// DrawLayer(layer);
|
|
||||||
Handles.EndGUI();
|
Handles.EndGUI();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -291,15 +273,24 @@ public class NanoBrainInspector : Editor {
|
|||||||
float margin = 10 + spacing / 2;
|
float margin = 10 + spacing / 2;
|
||||||
|
|
||||||
int row = 0;
|
int row = 0;
|
||||||
foreach (Synapse receiver in nucleus.synapses) {
|
List<PercepteiArray> drawnArrays = new();
|
||||||
Nucleus receiverNucleus = receiver.nucleus;
|
foreach (Synapse synapse in nucleus.synapses) {
|
||||||
|
|
||||||
Vector3 pos = new(250, margin + row * spacing, 0.0f);
|
Vector3 pos = new(250, margin + row * spacing, 0.0f);
|
||||||
Handles.color = Color.white;
|
Handles.color = Color.white;
|
||||||
Handles.DrawLine(parentPos, pos);
|
Handles.DrawLine(parentPos, pos);
|
||||||
|
if (synapse.nucleus is ArrayPerceptoid perceptoid) {
|
||||||
|
if (drawnArrays.Contains(perceptoid.array))
|
||||||
|
// We already drawn this array
|
||||||
|
continue;
|
||||||
|
|
||||||
DrawNucleus(receiverNucleus, pos, maxValue, size);
|
drawnArrays.Add(perceptoid.array);
|
||||||
row++;
|
DrawArray(perceptoid.array, pos, size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
DrawNucleus(synapse.nucleus, pos, maxValue, size);
|
||||||
|
row++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +303,7 @@ public class NanoBrainInspector : Editor {
|
|||||||
}
|
}
|
||||||
Handles.DrawSolidDisc(position, Vector3.forward, size);
|
Handles.DrawSolidDisc(position, Vector3.forward, size);
|
||||||
Vector3 labelPos = position - Vector3.down * (size + 0.2f); // below disc along up axis
|
Vector3 labelPos = position - Vector3.down * (size + 0.2f); // below disc along up axis
|
||||||
GUIStyle style = new GUIStyle(EditorStyles.label) {
|
GUIStyle style = new(EditorStyles.label) {
|
||||||
alignment = TextAnchor.UpperCenter,
|
alignment = TextAnchor.UpperCenter,
|
||||||
normal = { textColor = Color.white },
|
normal = { textColor = Color.white },
|
||||||
fontStyle = FontStyle.Bold
|
fontStyle = FontStyle.Bold
|
||||||
@ -335,15 +326,28 @@ public class NanoBrainInspector : Editor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawArray(PercepteiArray array, Vector3 position, float size) {
|
||||||
|
Vector3 offset = new(size/4, size/4, 0);
|
||||||
|
Handles.color = Color.darkGray;
|
||||||
|
Handles.DrawSolidDisc(position + offset * 2, Vector3.forward, size);
|
||||||
|
Handles.color = Color.lightGray;
|
||||||
|
Handles.DrawSolidDisc(position + offset, Vector3.forward, size);
|
||||||
|
Handles.color = Color.white;
|
||||||
|
Handles.DrawSolidDisc(position, Vector3.forward, size);
|
||||||
|
|
||||||
|
Vector3 labelPos = position - Vector3.down * (size + 0.2f); // below disc along up axis
|
||||||
|
GUIStyle style = new GUIStyle(EditorStyles.label) {
|
||||||
|
alignment = TextAnchor.UpperCenter,
|
||||||
|
normal = { textColor = Color.white },
|
||||||
|
fontStyle = FontStyle.Bold
|
||||||
|
};
|
||||||
|
Handles.Label(labelPos, array.name, style);
|
||||||
|
|
||||||
|
// To do: add HandleClick (see above) to expand the array
|
||||||
|
}
|
||||||
|
|
||||||
private void HandleMouseHover(Nucleus nucleus, Rect rect) {
|
private void HandleMouseHover(Nucleus nucleus, Rect rect) {
|
||||||
GUIContent tooltip;
|
GUIContent tooltip;
|
||||||
// if (nucleus is SensoryNeuroid sensoryNeuroid) {
|
|
||||||
// tooltip = new(
|
|
||||||
// $"{sensoryNeuroid.name}" +
|
|
||||||
// $"\nThing {sensoryNeuroid.receptor.thingType}" +
|
|
||||||
// $"\nValue: {nucleus.outputValue}");
|
|
||||||
// }
|
|
||||||
//else
|
|
||||||
if (nucleus is Perceptoid perceptoid) {
|
if (nucleus is Perceptoid perceptoid) {
|
||||||
if (perceptoid.receptor != null) {
|
if (perceptoid.receptor != null) {
|
||||||
tooltip = new(
|
tooltip = new(
|
||||||
@ -419,42 +423,43 @@ public class NanoBrainInspector : Editor {
|
|||||||
EditorGUILayout.LabelField(" ");
|
EditorGUILayout.LabelField(" ");
|
||||||
|
|
||||||
if (this.currentNucleus.synapses.Count > 0) {
|
if (this.currentNucleus.synapses.Count > 0) {
|
||||||
foreach (Synapse synapse in this.currentNucleus.synapses) {
|
Synapse[] synapses = this.currentNucleus.synapses.ToArray();
|
||||||
|
foreach (Synapse synapse in synapses) {
|
||||||
if (synapse.nucleus != null) {
|
if (synapse.nucleus != null) {
|
||||||
EditorGUILayout.Space();
|
EditorGUILayout.Space();
|
||||||
EditorGUI.BeginDisabledGroup(synapse.nucleus.isSleeping);
|
EditorGUI.BeginDisabledGroup(synapse.nucleus.isSleeping);
|
||||||
if (Application.isPlaying)
|
if (Application.isPlaying)
|
||||||
EditorGUILayout.FloatField(synapse.nucleus.name, synapse.nucleus.outputValue.magnitude * synapse.weight);
|
EditorGUILayout.FloatField(synapse.nucleus.name, synapse.nucleus.outputValue.magnitude * synapse.weight);
|
||||||
else
|
else {
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
EditorGUILayout.LabelField(synapse.nucleus.name);
|
EditorGUILayout.LabelField(synapse.nucleus.name);
|
||||||
|
if (GUILayout.Button("Disconnect"))
|
||||||
|
synapse.nucleus.RemoveReceiver(this.currentNucleus);
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
EditorGUI.indentLevel++;
|
EditorGUI.indentLevel++;
|
||||||
// EditorGUI.BeginChangeCheck();
|
|
||||||
synapse.weight = EditorGUILayout.FloatField("Weight", synapse.weight);
|
synapse.weight = EditorGUILayout.FloatField("Weight", synapse.weight);
|
||||||
|
|
||||||
// synapse.curvePreset = (Synapse.CurvePresets)EditorGUILayout.EnumPopup("Preset", synapse.curvePreset);
|
|
||||||
// if (EditorGUI.EndChangeCheck()) {
|
|
||||||
// synapse.curve = synapse.GenerateCurve();
|
|
||||||
// }
|
|
||||||
// if (synapse.curveMax > 0)
|
|
||||||
// EditorGUILayout.CurveField("Curve", synapse.curve, Color.cyan, new Rect(0, 0, 1, synapse.curveMax));
|
|
||||||
// else
|
|
||||||
// EditorGUILayout.CurveField("Curve", synapse.curve, Color.cyan, new Rect(0, synapse.curveMax, 1, -synapse.curveMax));
|
|
||||||
EditorGUI.indentLevel--;
|
EditorGUI.indentLevel--;
|
||||||
EditorGUI.EndDisabledGroup();
|
EditorGUI.EndDisabledGroup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//EditorGUI.indentLevel--;
|
|
||||||
}
|
}
|
||||||
if (GUILayout.Button("Add Neuron"))
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
ConnectNucleus(this.currentNucleus);
|
||||||
|
if (GUILayout.Button("Add Input Neuron"))
|
||||||
AddInputNeuron(this.currentNucleus);
|
AddInputNeuron(this.currentNucleus);
|
||||||
if (GUILayout.Button("Add Perceptoid"))
|
if (GUILayout.Button("Add Input Perceptoid"))
|
||||||
AddPerceptoid(this.currentNucleus);
|
AddPerceptoid(this.currentNucleus);
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
if (GUILayout.Button("Delete this neuron"))
|
if (GUILayout.Button("Delete this neuron"))
|
||||||
DeleteNeuron(this.currentNucleus);
|
DeleteNeuron(this.currentNucleus);
|
||||||
|
|
||||||
ConnectNucleus(this.currentNucleus);
|
//DisconnectNucleus(this.currentNucleus);
|
||||||
DisconnectNucleus(this.currentNucleus);
|
|
||||||
|
|
||||||
if (this.gameObject != null) {
|
if (this.gameObject != null) {
|
||||||
Vector3 worldVector = this.gameObject.transform.TransformVector(this.currentNucleus.outputValue);
|
Vector3 worldVector = this.gameObject.transform.TransformVector(this.currentNucleus.outputValue);
|
||||||
@ -498,9 +503,9 @@ public class NanoBrainInspector : Editor {
|
|||||||
if (this.currentNucleus.brain == null)
|
if (this.currentNucleus.brain == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//string[] names = this.currentNucleus.brain.perceptei.Select(i => i.name).ToArray();
|
IEnumerable<string> synapseNuclei = this.currentNucleus.synapses.Select(synapse => synapse.nucleus.name);
|
||||||
IEnumerable<string> perceptei = this.currentNucleus.brain.perceptei.Select(i => i.name);
|
IEnumerable<string> perceptei = this.currentNucleus.brain.perceptei.Select(i => i.name).Except(synapseNuclei);
|
||||||
IEnumerable<string> nuclei = this.currentNucleus.brain.nuclei.Select(i => i.name);
|
IEnumerable<string> nuclei = this.currentNucleus.brain.nuclei.Select(i => i.name).Except(synapseNuclei);
|
||||||
string[] names = perceptei.Concat(nuclei).ToArray();
|
string[] names = perceptei.Concat(nuclei).ToArray();
|
||||||
int selectedIndex = -1;
|
int selectedIndex = -1;
|
||||||
selectedIndex = EditorGUILayout.Popup("Connect to", selectedIndex, names);
|
selectedIndex = EditorGUILayout.Popup("Connect to", selectedIndex, names);
|
||||||
@ -527,32 +532,6 @@ public class NanoBrainInspector : Editor {
|
|||||||
synapse.nucleus.RemoveReceiver(this.currentNucleus);
|
synapse.nucleus.RemoveReceiver(this.currentNucleus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private Vector3 NodePosition(Nucleus nucleus, int layerNodeCount = 1) {
|
|
||||||
// if (this.neuroidPositions.ContainsKey(nucleus)) {
|
|
||||||
// Vector2Int nucleusPos = this.neuroidPositions[nucleus];
|
|
||||||
// return NodePosition(nucleusPos, layerNodeCount);
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// return Vector3.zero;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// private Vector3 NodePosition(Vector2Int location, int layerNodeCount = 1) {
|
|
||||||
// float spacing = 400f / layerNodeCount;
|
|
||||||
// float margin = 10 + spacing / 2;
|
|
||||||
// float size = 20;
|
|
||||||
// Vector3 parentPos = new(100 + location.x * 100 - size, margin + location.y * spacing - size, 0.1f);
|
|
||||||
// return parentPos;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// public void CreateEdge(string fromId, string toId) {
|
|
||||||
// if (fromId == toId) return;
|
|
||||||
// Undo.RecordObject(graph, "Create Edge");
|
|
||||||
// graph.edges.Add(new GraphEdge { fromNodeId = fromId, toNodeId = toId });
|
|
||||||
// EditorUtility.SetDirty(graph);
|
|
||||||
// Rebuild();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Start
|
#endregion Start
|
||||||
@ -573,29 +552,31 @@ public class NanoBrainInspector : Editor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// protected virtual void OnSceneGUI() {
|
|
||||||
// NanoBrain brain = target as NanoBrain;
|
|
||||||
// if (brain == null)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// Vector3 position = brain.transform.position;
|
|
||||||
// float radius = 1;
|
|
||||||
|
|
||||||
|
|
||||||
// Handles.DrawWireDisc(position, Vector3.up, radius); // horizontal circle
|
|
||||||
// Handles.DrawWireDisc(position, Vector3.right, radius); // X-plane
|
|
||||||
// Handles.DrawWireDisc(position, Vector3.forward, radius); // Z-plane
|
|
||||||
|
|
||||||
|
|
||||||
// // Debug.DrawRay(brain.transform.position, Vector3.forward, Color.magenta);
|
|
||||||
// // Handles.color = Color.green;
|
|
||||||
// // Handles.DrawLine(brain.transform.position, brain.transform.position + Vector3.up);
|
|
||||||
|
|
||||||
// // Handles.color = Color.yellow;
|
|
||||||
// // Vector3 worldForce = brain.transform.TransformDirection(this.currentNucleus.outputValue);
|
|
||||||
// // //Debug.DrawRay(position, worldForce * 10, Color.yellow);
|
|
||||||
// // Handles.DrawLine(position, position + worldForce * 10);
|
|
||||||
// }
|
|
||||||
|
|
||||||
#endregion Update
|
#endregion Update
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class GraphNodeWrapper : ScriptableObject {
|
||||||
|
// expose fields that map to GraphNode
|
||||||
|
public string title;
|
||||||
|
public Vector2 position;
|
||||||
|
Nucleus node;
|
||||||
|
NanoBrain graph; // needed to write back and mark dirty
|
||||||
|
|
||||||
|
public GraphNodeWrapper Init(Nucleus node, NanoBrain graphAsset) {
|
||||||
|
this.node = node;
|
||||||
|
this.graph = graphAsset;
|
||||||
|
this.title = " A " + node.name;
|
||||||
|
//position = node.position;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
void OnValidate() {
|
||||||
|
if (node != null) {
|
||||||
|
node.name = title;
|
||||||
|
//node.position = position;
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (graph != null)
|
||||||
|
UnityEditor.EditorUtility.SetDirty(graph);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using LinearAlgebra;
|
|
||||||
|
|
||||||
[CreateAssetMenu(menuName = "Passer/NanoBrain")]
|
[CreateAssetMenu(menuName = "Passer/NanoBrain")]
|
||||||
public class NanoBrain : ScriptableObject, ISerializationCallbackReceiver {
|
public class NanoBrain : ScriptableObject, ISerializationCallbackReceiver {
|
||||||
@ -19,11 +18,8 @@ public class NanoBrain : ScriptableObject, ISerializationCallbackReceiver {
|
|||||||
public Nucleus root;
|
public Nucleus root;
|
||||||
public int rootId;
|
public int rootId;
|
||||||
|
|
||||||
// public Perception perception;
|
|
||||||
|
|
||||||
public NanoBrain() {
|
public NanoBrain() {
|
||||||
this.root = new Neuroid(this, "Root");
|
this.root = new Neuroid(this, "Root");
|
||||||
// this.perception = new Perception(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Neuroid AddNeuron(string name) {
|
public Neuroid AddNeuron(string name) {
|
||||||
@ -32,18 +28,10 @@ public class NanoBrain : ScriptableObject, ISerializationCallbackReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateNuclei() {
|
public void UpdateNuclei() {
|
||||||
foreach (Nucleus nucleus in nuclei) {
|
foreach (Nucleus nucleus in nuclei)
|
||||||
//nucleus.stale++;
|
nucleus.IncreaseAge();
|
||||||
nucleus.IncreaseAge();
|
foreach (Perceptoid perception in perceptei)
|
||||||
// if (nucleus.isSleeping)
|
perception.IncreaseAge();
|
||||||
// nucleus.outputValue = Spherical.zero;
|
|
||||||
}
|
|
||||||
foreach (Perceptoid perception in perceptei) {
|
|
||||||
//perception.stale++;
|
|
||||||
perception.IncreaseAge();
|
|
||||||
// if (perception.isSleeping)
|
|
||||||
// perception.outputValue = Spherical.zero;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnBeforeSerialize() {
|
public void OnBeforeSerialize() {
|
||||||
@ -57,14 +45,8 @@ public class NanoBrain : ScriptableObject, ISerializationCallbackReceiver {
|
|||||||
nucleus.Rebuild(this);
|
nucleus.Rebuild(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// List<Nucleus> rebuildNuclei = new();
|
foreach (Perceptoid perceptoid in this.perceptei.ToArray())
|
||||||
// foreach (Nucleus nucleus in this.nuclei.ToArray()) {
|
perceptoid.Rebuild(this);
|
||||||
// rebuildNuclei.Add(Nucleus.RebuildType(this, nucleus));
|
|
||||||
// }
|
|
||||||
// this.nuclei = rebuildNuclei;
|
|
||||||
foreach (Perceptoid perceptoid in this.perceptei.ToArray()) {
|
|
||||||
perceptoid.Rebuild(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (System.Exception) { }
|
catch (System.Exception) { }
|
||||||
this.GarbageCollection();
|
this.GarbageCollection();
|
||||||
@ -85,9 +67,6 @@ public class NanoBrain : ScriptableObject, ISerializationCallbackReceiver {
|
|||||||
if (nucleus.brain == null)
|
if (nucleus.brain == null)
|
||||||
nucleus.brain = this;
|
nucleus.brain = this;
|
||||||
|
|
||||||
if (nucleus.name == "Boid1")
|
|
||||||
Debug.Log(" Found boiid1");
|
|
||||||
|
|
||||||
visitedNuclei.Add(nucleus);
|
visitedNuclei.Add(nucleus);
|
||||||
if (nucleus.synapses != null) {
|
if (nucleus.synapses != null) {
|
||||||
HashSet<Synapse> visitedSynapses = new();
|
HashSet<Synapse> visitedSynapses = new();
|
||||||
@ -105,7 +84,6 @@ public class NanoBrain : ScriptableObject, ISerializationCallbackReceiver {
|
|||||||
if (receiver != null && receiver.nucleus != null) {
|
if (receiver != null && receiver.nucleus != null) {
|
||||||
visitedReceivers.Add(receiver);
|
visitedReceivers.Add(receiver);
|
||||||
visitedNuclei.Add(receiver.nucleus);
|
visitedNuclei.Add(receiver.nucleus);
|
||||||
//MarkNuclei(visitedNuclei, receiver.nucleus);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nucleus.receivers.RemoveAll(receiver => visitedReceivers.Contains(receiver) == false);
|
nucleus.receivers.RemoveAll(receiver => visitedReceivers.Contains(receiver) == false);
|
||||||
@ -4,18 +4,30 @@ public class NanoBrainComponent : MonoBehaviour {
|
|||||||
public NanoBrain defaultBrain;
|
public NanoBrain defaultBrain;
|
||||||
private NanoBrain brainInstance;
|
private NanoBrain brainInstance;
|
||||||
|
|
||||||
public Nucleus root {
|
public Nucleus root => brainInstance.root;
|
||||||
get {
|
|
||||||
return brainInstance.root;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public NanoBrain brain {
|
public NanoBrain brain {
|
||||||
get {
|
get {
|
||||||
if (brainInstance == null && defaultBrain != null) {
|
if (brainInstance == null && defaultBrain != null) {
|
||||||
brainInstance = Instantiate(defaultBrain);
|
brainInstance = Instantiate(defaultBrain);
|
||||||
brainInstance.name = defaultBrain.name + " (Instance)";
|
brainInstance.name = defaultBrain.name + " (Instance)";
|
||||||
|
|
||||||
|
SwarmControl sc = FindFirstObjectByType<SwarmControl>();
|
||||||
|
UpdateWeight(brainInstance, "Avoidance", sc.avoidanceForce);
|
||||||
|
UpdateWeight(brainInstance, "Cohesion", sc.cohesionForce);
|
||||||
|
UpdateWeight(brainInstance, "Separation", sc.separationForce);
|
||||||
|
UpdateWeight(brainInstance, "Alignment", sc.alignmentForce);
|
||||||
}
|
}
|
||||||
return brainInstance;
|
return brainInstance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void UpdateWeight(NanoBrain brain, string name, float weight) {
|
||||||
|
Nucleus root = brain.root;
|
||||||
|
foreach (Synapse synapse in root.synapses) {
|
||||||
|
if (synapse.nucleus.name == name) {
|
||||||
|
synapse.weight = weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -376,12 +376,11 @@ MonoBehaviour:
|
|||||||
speed: 1
|
speed: 1
|
||||||
inertia: 0.7
|
inertia: 0.7
|
||||||
alignmentForce: 0.5
|
alignmentForce: 0.5
|
||||||
cohesionForce: 2.2
|
cohesionForce: 0.1
|
||||||
separationForce: -5
|
separationForce: -0.1
|
||||||
avoidanceForce: 1
|
avoidanceForce: 1
|
||||||
separationDistance: 0.3
|
separationDistance: 0.3
|
||||||
perceptionDistance: 2
|
perceptionDistance: 2
|
||||||
boundaryForce: 5
|
|
||||||
spaceSize: {x: 10, y: 10, z: 10}
|
spaceSize: {x: 10, y: 10, z: 10}
|
||||||
boundaryWidth: {x: 1, y: 1, z: 1}
|
boundaryWidth: {x: 1, y: 1, z: 1}
|
||||||
--- !u!114 &301943979
|
--- !u!114 &301943979
|
||||||
|
|||||||
@ -46,9 +46,14 @@ public class Boid : MonoBehaviour {
|
|||||||
|
|
||||||
int thingId = neighbour.GetInstanceID();
|
int thingId = neighbour.GetInstanceID();
|
||||||
|
|
||||||
Vector3 localPosition = this.transform.InverseTransformPoint(neighbour.transform.position);
|
Vector3 localPosition = this.transform.InverseTransformPoint(neighbour.transform.position);
|
||||||
|
float d = localPosition.magnitude;
|
||||||
|
if (d <= sc.separationDistance)
|
||||||
|
localPosition = localPosition.normalized * 0.01f;
|
||||||
|
else
|
||||||
|
localPosition = localPosition.normalized * (localPosition.magnitude - sc.separationDistance);
|
||||||
if (localPosition.sqrMagnitude > 0)
|
if (localPosition.sqrMagnitude > 0)
|
||||||
boidReceptor?.ProcessStimulus(thingId, localPosition);
|
boidReceptor?.ProcessStimulus(thingId, localPosition, neighbour.name);
|
||||||
|
|
||||||
Vector3 localVelocity = this.transform.InverseTransformVector(neighbour.velocity);
|
Vector3 localVelocity = this.transform.InverseTransformVector(neighbour.velocity);
|
||||||
if (localVelocity.sqrMagnitude > 0)
|
if (localVelocity.sqrMagnitude > 0)
|
||||||
|
|||||||
@ -13,21 +13,21 @@ public class SwarmControl_Editor : Editor {
|
|||||||
NanoBrain[] nanoBrains = FindObjectsByType<NanoBrain>(FindObjectsSortMode.None);
|
NanoBrain[] nanoBrains = FindObjectsByType<NanoBrain>(FindObjectsSortMode.None);
|
||||||
|
|
||||||
foreach (NanoBrain brain in nanoBrains) {
|
foreach (NanoBrain brain in nanoBrains) {
|
||||||
UpdateWeight(brain, "Avoidance", swarmControl.avoidanceForce);
|
NanoBrainComponent.UpdateWeight(brain, "Avoidance", swarmControl.avoidanceForce);
|
||||||
UpdateWeight(brain, "Cohesion", swarmControl.cohesionForce);
|
NanoBrainComponent.UpdateWeight(brain, "Cohesion", swarmControl.cohesionForce);
|
||||||
UpdateWeight(brain, "Separation", swarmControl.separationForce);
|
NanoBrainComponent.UpdateWeight(brain, "Separation", swarmControl.separationForce);
|
||||||
UpdateWeight(brain, "Alignment", swarmControl.alignmentForce);
|
NanoBrainComponent.UpdateWeight(brain, "Alignment", swarmControl.alignmentForce);
|
||||||
}
|
}
|
||||||
Debug.Log("Updated weights");
|
Debug.Log("Updated weights");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void UpdateWeight(NanoBrain brain, string name, float weight) {
|
// protected void UpdateWeight(NanoBrain brain, string name, float weight) {
|
||||||
Nucleus root = brain.root;
|
// Nucleus root = brain.root;
|
||||||
foreach (Synapse synapse in root.synapses) {
|
// foreach (Synapse synapse in root.synapses) {
|
||||||
if (synapse.nucleus.name == name) {
|
// if (synapse.nucleus.name == name) {
|
||||||
synapse.weight = weight;
|
// synapse.weight = weight;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
@ -14,7 +14,7 @@ public class SwarmControl : MonoBehaviour
|
|||||||
// public float bodyForce = 20;
|
// public float bodyForce = 20;
|
||||||
public float perceptionDistance = 1.0f;
|
public float perceptionDistance = 1.0f;
|
||||||
|
|
||||||
public float boundaryForce = 2.0f;
|
//public float boundaryForce = 2.0f;
|
||||||
public Vector3 spaceSize = new (10, 10, 10);
|
public Vector3 spaceSize = new (10, 10, 10);
|
||||||
public Vector3 boundaryWidth = Vector3.one * 1.0f;
|
public Vector3 boundaryWidth = Vector3.one * 1.0f;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user