Cleanup
This commit is contained in:
parent
2134495045
commit
a22e4b149a
@ -51,7 +51,6 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Assets/NanoBrain/VisualEditor/Editor/NanoBrainEditor.cs" />
|
||||
<Compile Include="Assets/NanoBrain/VisualEditor/Editor/NanoBrainInspector.cs" />
|
||||
<Compile Include="Assets/NanoBrain/Editor/NanoBrain_Editor.cs" />
|
||||
<Compile Include="Assets/Scenes/Boids/Scripts/Editor/SwarmControl_Editor.cs" />
|
||||
<Compile Include="Assets/NanoBrain/Editor/NeuroidWindow.cs" />
|
||||
<Compile Include="Assets/NanoBrain/VisualEditor/Editor/NanoBrainComponent_Editor.cs" />
|
||||
|
||||
@ -58,23 +58,19 @@
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/Vector2FloatTest.cs" />
|
||||
<Compile Include="Assets/Scenes/Boids/Scripts/SwarmSpawner.cs" />
|
||||
<Compile Include="Assets/NanoBrain/Perceptoid.cs" />
|
||||
<Compile Include="Assets/NanoBrain/NeuroidBehaviour.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Direction.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Vector2Float.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/SwingTwistTest.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Vector3Int.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Vector3Float.cs" />
|
||||
<Compile Include="Assets/NanoBrain/Receptor.cs" />
|
||||
<Compile Include="Assets/NanoBrain/NanoBrain.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Matrix.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Decomposition.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Quat32.cs" />
|
||||
<Compile Include="Assets/NanoBrain/SensoryNeuroid.cs" />
|
||||
<Compile Include="Assets/NanoBrain/VisualEditor/NanoBrainComponent.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Vector2Int.cs" />
|
||||
<Compile Include="Assets/Scenes/Boids/Scripts/SwarmControl.cs" />
|
||||
<Compile Include="Assets/Scenes/Boids/Scripts/RoamingNucleus.cs" />
|
||||
<Compile Include="Assets/NanoBrain/Perception.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Spherical.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/Vector3FloatTest.cs" />
|
||||
<Compile Include="Assets/Scenes/Boids/Scripts/SwarmingNucleus.cs" />
|
||||
@ -83,11 +79,9 @@
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/SwingTwist.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/SphericalTest.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/test/Vector3IntTest.cs" />
|
||||
<Compile Include="Assets/NanoBrain/VisualEditor/NucleusObject.cs" />
|
||||
<Compile Include="Assets/NanoBrain/Neuroid.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Angle.cs" />
|
||||
<Compile Include="Assets/NanoBrain/LinearAlgebra/src/Float.cs" />
|
||||
<Compile Include="Assets/NanoBrain/VisualEditor/NeuroidObject.cs" />
|
||||
<Compile Include="Assets/NanoBrain/Nucleus.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@ -1,272 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor(typeof(NanoBrain))]
|
||||
public class NanoBrain_Editor : Editor {
|
||||
private Nucleus currentNucleus;
|
||||
private List<NeuroidLayer> layers = new();
|
||||
private Dictionary<Nucleus, Vector2Int> neuroidPositions = new();
|
||||
|
||||
protected bool breakOnWake = false;
|
||||
|
||||
#region Start
|
||||
|
||||
private void OnEnable() {
|
||||
// NanoBrain brain = target as NanoBrain;
|
||||
// if (brain == null)
|
||||
// return;
|
||||
|
||||
// if (brain.rootNucleus == null) {
|
||||
// brain.rootNucleus = CreateInstance<NucleusObj>();
|
||||
// EditorUtility.SetDirty(brain.rootNucleus);
|
||||
// }
|
||||
|
||||
SelectNeuron();
|
||||
}
|
||||
|
||||
private void SelectNeuron() {
|
||||
// GameObject selectedObject = ((NanoBrain)target).gameObject;
|
||||
// if (!selectedObject.TryGetComponent(out Boid boid))
|
||||
// return;
|
||||
|
||||
// Nucleus neuroid = boid.totalForce;
|
||||
// this.currentNucleus = neuroid;
|
||||
|
||||
// BuildLayers();
|
||||
// Debug.Log($"Layercount = {this.layers.Count}");
|
||||
}
|
||||
|
||||
#endregion Start
|
||||
|
||||
#region Update
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
if (this.currentNucleus == null)
|
||||
return;
|
||||
|
||||
breakOnWake = EditorGUILayout.Toggle("Break on wake", breakOnWake);
|
||||
if (breakOnWake && currentNucleus is Neuroid currentNeuroid) {
|
||||
if (!currentNeuroid.isSleeping)
|
||||
Debug.Break();
|
||||
}
|
||||
|
||||
DrawGraph();
|
||||
|
||||
EditorGUILayout.TextField("Name", currentNucleus.name);
|
||||
EditorGUILayout.Vector3Field("Output Value", currentNucleus.outputValue.ToVector3());
|
||||
if (currentNucleus.synapses.Count > 0) {
|
||||
EditorGUI.indentLevel++;
|
||||
//foreach ((Nucleus nucleus, float weight) in currentNucleus.synapses) {
|
||||
foreach (Synapse synapse in currentNucleus.synapses) {
|
||||
Nucleus nucleus = synapse.nucleus;
|
||||
float weight = synapse.weight;
|
||||
|
||||
EditorGUI.BeginDisabledGroup(nucleus.isSleeping);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.Vector3Field(nucleus.name, nucleus.outputValue.ToVector3());
|
||||
EditorGUILayout.FloatField(weight, GUILayout.Width(50));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
DrawDefaultInspector();
|
||||
}
|
||||
|
||||
private void BuildLayers() {
|
||||
// A temporary list to track what's been added to layers
|
||||
this.layers = new();
|
||||
int layerIx = 0;
|
||||
|
||||
Nucleus selectedNucleus = this.currentNucleus;
|
||||
if (selectedNucleus == null)
|
||||
return;
|
||||
NeuroidLayer currentLayer = new() { ix = layerIx };
|
||||
|
||||
//foreach (Neuroid outputNeuroid in selectedNucleus.receivers) {
|
||||
foreach (Receiver receiver in selectedNucleus.receivers) {
|
||||
Nucleus outputNeuroid = receiver.nucleus;
|
||||
if (outputNeuroid != null) {
|
||||
AddToLayer(currentLayer, outputNeuroid);
|
||||
// Debug.Log($"layer {layerIx} nucleus {outputNeuroid.name}");
|
||||
}
|
||||
}
|
||||
if (currentLayer.neuroids.Count > 0) {
|
||||
this.layers.Add(currentLayer);
|
||||
layerIx++;
|
||||
currentLayer = new() { ix = layerIx };
|
||||
}
|
||||
|
||||
AddToLayer(currentLayer, selectedNucleus);
|
||||
this.layers.Add(currentLayer);
|
||||
// Debug.Log($"layer {layerIx} nucleus {selectedNucleus.name}");
|
||||
|
||||
layerIx++;
|
||||
currentLayer = new() { ix = layerIx };
|
||||
|
||||
//foreach (Nucleus input in selectedNucleus.synapses.Keys) {
|
||||
foreach (Synapse synapse in selectedNucleus.synapses) {
|
||||
Nucleus input = synapse.nucleus;
|
||||
AddToLayer(currentLayer, input);
|
||||
// Debug.Log($"layer {layerIx} nucleus {input.name}");
|
||||
}
|
||||
if (currentLayer.neuroids.Count > 0) {
|
||||
this.layers.Add(currentLayer);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddToLayer(NeuroidLayer layer, Nucleus nucleus) {
|
||||
layer.neuroids.Add(nucleus);
|
||||
nucleus.layerIx = layer.ix;
|
||||
// Store its position
|
||||
Vector2Int neuroidPosition = new(layer.ix, layer.neuroids.Count - 1);
|
||||
neuroidPositions[nucleus] = neuroidPosition;
|
||||
|
||||
}
|
||||
|
||||
private void DrawGraph() {
|
||||
if (currentNucleus == null)
|
||||
return;
|
||||
Rect outer = EditorGUILayout.GetControlRect(false, 420);
|
||||
GUI.BeginGroup(outer);
|
||||
foreach (NeuroidLayer layer in layers)
|
||||
DrawLayer(layer);
|
||||
GUI.EndGroup();
|
||||
}
|
||||
|
||||
private void DrawLayer(NeuroidLayer layer) {
|
||||
int nodeCount = layer.neuroids.Count;
|
||||
float maxValue = 0;
|
||||
foreach (Nucleus nucleus in layer.neuroids) {
|
||||
if (nucleus is Neuroid neuroid) {
|
||||
float value = neuroid.outputValue.magnitude;
|
||||
if (value > maxValue)
|
||||
maxValue = value;
|
||||
}
|
||||
}
|
||||
float spacing = 400f / nodeCount;
|
||||
float margin = 10 + spacing / 2;
|
||||
foreach (Nucleus layerNucleus in layer.neuroids) {
|
||||
if (layerNucleus is Neuroid layerNeuroid) {
|
||||
Vector2Int layerNeuroidPos = this.neuroidPositions[layerNeuroid];
|
||||
Vector3 parentPos = new(100 + layerNeuroidPos.x * 100, margin + layerNeuroidPos.y * spacing, 0.1f);
|
||||
|
||||
//int i = 0;
|
||||
float inputSpacing = 400f / layerNeuroid.synapses.Count;
|
||||
float inputMargin = 10 + inputSpacing / 2;
|
||||
// int minStale = 10000;
|
||||
//foreach ((Nucleus nucleus, float weight) in layerNeuroid.synapses) {
|
||||
foreach (Synapse synapse in layerNeuroid.synapses) {
|
||||
Nucleus nucleus = synapse.nucleus;
|
||||
float weight = synapse.weight;
|
||||
if (this.neuroidPositions.ContainsKey(nucleus)) {
|
||||
Vector2Int inputNeuroidPos = this.neuroidPositions[nucleus];
|
||||
if (inputNeuroidPos.x == layerNeuroidPos.x + 1) {
|
||||
Vector3 pos = new(100 + inputNeuroidPos.x * 100, inputMargin + inputNeuroidPos.y * inputSpacing, 0.0f);
|
||||
|
||||
float brightness = weight / 10.0f;
|
||||
Handles.color = new Color(brightness, brightness, brightness);
|
||||
Handles.DrawLine(parentPos, pos);
|
||||
}
|
||||
}
|
||||
// if (nucleus is Neuroid neuroid && neuroid.stale < minStale)
|
||||
// minStale = neuroid.stale;
|
||||
}
|
||||
|
||||
// if (layerNeuroid.synapses.Count > 0 && minStale > 2 && layerNeuroid.stale < 3)
|
||||
// Debug.LogWarning($"Strange {minStale} is big duing update");
|
||||
|
||||
|
||||
float size = 20;
|
||||
if (layerNeuroid.isSleeping)
|
||||
Handles.color = Color.darkRed;
|
||||
else {
|
||||
float brightness = layerNeuroid.outputValue.magnitude / maxValue;
|
||||
Handles.color = new Color(brightness, brightness, brightness);
|
||||
}
|
||||
Handles.DrawSolidDisc(parentPos, Vector3.forward, size);
|
||||
Vector3 labelPos = parentPos - 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, layerNeuroid.name, style);
|
||||
|
||||
Rect neuronRect = new(parentPos.x - size, parentPos.y - size, size * 2, size * 2);
|
||||
int id = GUIUtility.GetControlID(FocusType.Passive);
|
||||
Event e = Event.current;
|
||||
EventType et = e.GetTypeForControl(id);
|
||||
if (e != null && neuronRect.Contains(e.mousePosition)) {
|
||||
// Process Hover
|
||||
HandleMouseHover(layerNeuroid, neuronRect);
|
||||
// Process click
|
||||
if (et == EventType.MouseDown && e.button == 0) {
|
||||
// Consume the event so the scene doesn't also handle it
|
||||
e.Use();
|
||||
HandleDiscClicked(layerNeuroid);
|
||||
}
|
||||
}
|
||||
//i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleMouseHover(Neuroid neuroid, Rect rect) {
|
||||
GUIContent tooltip;
|
||||
if (neuroid is SensoryNeuroid sensoryNeuroid) {
|
||||
tooltip = new(
|
||||
$"{sensoryNeuroid.name}" +
|
||||
$"\nThing {sensoryNeuroid.receptor.thingType}" +
|
||||
$"\nValue: {neuroid.outputValue}");
|
||||
}
|
||||
else {
|
||||
tooltip = new(
|
||||
$"{neuroid.name}" +
|
||||
$"\nsynapse count {neuroid.synapses.Count}" +
|
||||
$"\nValue: {neuroid.outputValue}");
|
||||
}
|
||||
|
||||
Vector2 mousePosition = Event.current.mousePosition;
|
||||
|
||||
// Display tooltip with some offset
|
||||
Vector2 tooltipSize = GUI.skin.box.CalcSize(tooltip);
|
||||
Rect tooltipRect = new Rect(mousePosition.x + 10, mousePosition.y + 10, tooltipSize.x, tooltipSize.y);
|
||||
|
||||
GUI.Box(tooltipRect, tooltip);
|
||||
}
|
||||
|
||||
private void HandleDiscClicked(Nucleus nucleus) {
|
||||
this.currentNucleus = nucleus;
|
||||
BuildLayers();
|
||||
}
|
||||
|
||||
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.ToVector3());
|
||||
//Debug.DrawRay(position, worldForce * 10, Color.yellow);
|
||||
Handles.DrawLine(position, position + worldForce * 10);
|
||||
}
|
||||
|
||||
#endregion Update
|
||||
}
|
||||
@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2299b68d073cc5c31915f591deb79ddc
|
||||
@ -241,18 +241,18 @@ public class GraphEditorWindow : EditorWindow {
|
||||
|
||||
private void HandleMouseHover(Neuroid neuroid, Rect rect) {
|
||||
GUIContent tooltip;
|
||||
if (neuroid is SensoryNeuroid sensoryNeuroid) {
|
||||
tooltip = new(
|
||||
$"{sensoryNeuroid.name}" +
|
||||
$"\nThing {sensoryNeuroid.receptor.thingType}" +
|
||||
$"\nValue: {neuroid.outputValue}");
|
||||
}
|
||||
else {
|
||||
// if (neuroid is SensoryNeuroid sensoryNeuroid) {
|
||||
// tooltip = new(
|
||||
// $"{sensoryNeuroid.name}" +
|
||||
// $"\nThing {sensoryNeuroid.receptor.thingType}" +
|
||||
// $"\nValue: {neuroid.outputValue}");
|
||||
// }
|
||||
// else {
|
||||
tooltip = new(
|
||||
$"{neuroid.name}" +
|
||||
$"\nsynapse count {neuroid.synapses.Count}" +
|
||||
$"\nValue: {neuroid.outputValue}");
|
||||
}
|
||||
// }
|
||||
|
||||
Vector2 mousePosition = Event.current.mousePosition;
|
||||
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class NanoBrain : MonoBehaviour {
|
||||
|
||||
// public NucleusObj rootNucleus;
|
||||
|
||||
// public List<Neuroid> neuroids = new();
|
||||
|
||||
// public Neuroid AddNeuron(string name) {
|
||||
// Neuroid neuroid = new(this, name);
|
||||
// return neuroid;
|
||||
// }
|
||||
|
||||
// public void UpdateNeurons() {
|
||||
// foreach (Neuroid neuroid in neuroids) {
|
||||
// neuroid.stale++;
|
||||
// if (neuroid.isSleeping)
|
||||
// neuroid.outputValue = Vector3.zero;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74e1478743ac3bc078cbe8501c287e98
|
||||
@ -99,9 +99,7 @@ public class Neuroid : Nucleus {
|
||||
return;
|
||||
}
|
||||
|
||||
this.outputValue = result; //Spherical.FromVector3(resultVector);
|
||||
//this.stale = 0;
|
||||
//this.Refresh();
|
||||
this.outputValue = result;
|
||||
|
||||
foreach (Receiver receiver in this.receivers) {
|
||||
if (receiver.nucleus is Neuroid neuroid)
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class NeuroidBehaviour : MonoBehaviour
|
||||
{
|
||||
public Neuroid neuroid;
|
||||
public GameObject thing;
|
||||
|
||||
public void Start() {
|
||||
Debug.Log("Neuroid start");
|
||||
}
|
||||
public void Update() {
|
||||
Debug.Log("Neuroid update");
|
||||
}
|
||||
}
|
||||
@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dded3a10fb4fd894383b44483dd47382
|
||||
@ -1,110 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[System.Serializable]
|
||||
public class Perception : Nucleus {
|
||||
public SensoryNeuroid[] sensoryNeuroids = new SensoryNeuroid[7];
|
||||
|
||||
[System.Serializable]
|
||||
public class Receiver {
|
||||
public int thingType = 0;
|
||||
public Nucleus neuroid;
|
||||
}
|
||||
|
||||
//public HashSet<Receiver> positionReceivers { get; protected set; }
|
||||
public List<Receiver> positionReceivers;
|
||||
//public HashSet<Receiver> velocityReceivers { get; protected set; }
|
||||
public List<Receiver> velocityReceivers;
|
||||
|
||||
public Perception(NanoBrainObj brain) : base("Perception") {
|
||||
this.positionReceivers = new();
|
||||
this.velocityReceivers = new();
|
||||
}
|
||||
|
||||
public Perceptoid GetPerception(int thingType = 0) {
|
||||
foreach (Nucleus nucleus in this.brain.nuclei) {
|
||||
if (nucleus is Perceptoid perceptoid && (thingType == 0 || perceptoid.receptor.thingType == thingType))
|
||||
return perceptoid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// public void SendPositions(Nucleus receivingNeuroid, int thingType = 0, float weight = 1.0f) {
|
||||
// Receiver receiver = new() {
|
||||
// thingType = thingType,
|
||||
// neuroid = receivingNeuroid
|
||||
// };
|
||||
// positionReceivers.Add(receiver);
|
||||
// foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
|
||||
// if (neuroid != null) {
|
||||
// neuroid.AddReceiver(receivingNeuroid);
|
||||
// receivingNeuroid.SetWeight(neuroid, weight);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// public void SendVelocities(Nucleus receivingNeuroid, int thingType = 0, float weight = 1.0f) {
|
||||
// Receiver receiver = new() {
|
||||
// thingType = thingType,
|
||||
// neuroid = receivingNeuroid
|
||||
// };
|
||||
// velocityReceivers.Add(receiver);
|
||||
// foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
|
||||
// if (neuroid != null && neuroid.velocityNeuroid != null) {
|
||||
// neuroid.velocityNeuroid.AddReceiver(receivingNeuroid);
|
||||
// receivingNeuroid.SetWeight(neuroid, weight);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public void ProcessStimulus(int thingId, int thingType, Vector3 localPosition, string name = "Sensing") {
|
||||
int availableIx = -1;
|
||||
int leastInterestingIx = -1;
|
||||
for (int i = 0; i < sensoryNeuroids.Length; i++) {
|
||||
if (sensoryNeuroids[i] == null)
|
||||
availableIx = i;
|
||||
else if (sensoryNeuroids[i].receptor.thingType == thingId) {
|
||||
//sensoryNeuroids[i].receptor.position = localPosition;
|
||||
sensoryNeuroids[i].receptor.ProcessStimulus(999, localPosition);
|
||||
return;
|
||||
}
|
||||
if (availableIx == -1) {
|
||||
if (sensoryNeuroids[i].isSleeping)
|
||||
leastInterestingIx = i;
|
||||
else if (sensoryNeuroids[i] != null) {
|
||||
if (leastInterestingIx == -1 || sensoryNeuroids[leastInterestingIx].receptor.localPosition.magnitude > sensoryNeuroids[i].receptor.localPosition.magnitude)
|
||||
leastInterestingIx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (availableIx == -1)
|
||||
availableIx = leastInterestingIx;
|
||||
|
||||
if (availableIx != -1) {
|
||||
SensoryNeuroid neuroid;
|
||||
if (sensoryNeuroids[availableIx] != null) {
|
||||
Debug.Log($"replace receptor for {thingId} at {availableIx}");
|
||||
neuroid = sensoryNeuroids[availableIx];
|
||||
neuroid.Replace(thingId, name);
|
||||
}
|
||||
else {
|
||||
Debug.Log($"new receptor for {thingId} at {availableIx}");
|
||||
neuroid = new(brain, thingId, name);
|
||||
sensoryNeuroids[availableIx] = neuroid;
|
||||
}
|
||||
foreach (Receiver receiver in positionReceivers) {
|
||||
if (receiver.thingType == 0 || receiver.thingType == thingType) {
|
||||
Debug.Log("Add position receiver");
|
||||
receiver.neuroid.GetInputFrom(neuroid);
|
||||
}
|
||||
}
|
||||
// foreach (Receiver receiver in velocityReceivers) {
|
||||
// if (receiver.thingType == 0 || receiver.thingType == thingType)
|
||||
// receiver.neuroid.GetInputFrom(neuroid.velocityNeuroid);
|
||||
// }
|
||||
|
||||
//neuroid.receptor.position = localPosition;
|
||||
neuroid.receptor.ProcessStimulus(333, localPosition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37d94d399d30e6eb996236adabad87ee
|
||||
@ -48,19 +48,6 @@ public class Perceptoid : Neuroid {
|
||||
|
||||
#endregion Serialization
|
||||
|
||||
// public Perceptoid(NanoBrainObj brain, string name) : base(name) {
|
||||
// this.brain = brain;
|
||||
// if (this.brain != null) {
|
||||
// this.brain.perceptei.Add(this);
|
||||
// }
|
||||
// else
|
||||
// Debug.LogError("No neuroid network");
|
||||
|
||||
// this.nucleusType = nameof(Perceptoid);
|
||||
// this.name = name;
|
||||
// this.receptor = new Receptor(this);
|
||||
// }
|
||||
|
||||
public Perceptoid(NanoBrainObj brain, int thingType, string name = "sensor") : base(name) {
|
||||
this.brain = brain;
|
||||
if (this.brain != null) {
|
||||
@ -74,65 +61,22 @@ public class Perceptoid : Neuroid {
|
||||
this.thingType = thingType;
|
||||
this.receptor = Receptor.GetReceptor(brain, thingType);
|
||||
this.receptor.perceptei.Add(this);
|
||||
// this.velocityNeuroid = new(brain, name + ": velocity");
|
||||
// // The velocity neuroid received position data from this
|
||||
// this.AddReceiver(velocityNeuroid);
|
||||
}
|
||||
|
||||
public void Replace(int thingType, string name = "sensor") {
|
||||
this.name = name;
|
||||
|
||||
//this.thingType = thingType;
|
||||
this.thingType = thingType;
|
||||
this.receptor.thingType = thingType;
|
||||
this.receptor.localPosition = Spherical.zero;
|
||||
|
||||
this.outputValue = Spherical.zero;
|
||||
this.receivers = new();
|
||||
// this.AddReceiver(velocityNeuroid);
|
||||
|
||||
// this.velocityNeuroid.Replace(name + ": velocity");
|
||||
}
|
||||
|
||||
public override void UpdateState() {
|
||||
Vector3 result = receptor.localPosition.ToVector3();
|
||||
foreach (Synapse synapse in this.synapses) {
|
||||
Nucleus nucleus = synapse.nucleus;
|
||||
float weight = synapse.weight;
|
||||
Vector3 direction = nucleus.outputValue.normalized.ToVector3();
|
||||
float magnitude = nucleus.outputValue.magnitude;
|
||||
|
||||
magnitude = weight * Mathf.Pow(magnitude, exponent);
|
||||
if (inverse)
|
||||
magnitude = 1 / magnitude;
|
||||
result += direction * magnitude;
|
||||
}
|
||||
if (average && this.synapses.Count > 0)
|
||||
result /= this.synapses.Count + 1;
|
||||
|
||||
this.outputValue = Spherical.FromVector3(result);
|
||||
foreach (Receiver receiver in this.receivers)
|
||||
if (receiver.nucleus is Neuroid neuroid)
|
||||
neuroid.SetInput(this);
|
||||
//this.stale = 0;
|
||||
//this.Refresh();
|
||||
}
|
||||
|
||||
public void UpdateState(int thingId, Spherical receptorValue) {
|
||||
this.thingId = thingId;
|
||||
Spherical result = receptorValue;
|
||||
// foreach (Synapse synapse in this.synapses) {
|
||||
// Nucleus nucleus = synapse.nucleus;
|
||||
// float weight = synapse.weight;
|
||||
// Vector3 direction = nucleus.outputValue.normalized;
|
||||
// float magnitude = nucleus.outputValue.magnitude;
|
||||
|
||||
// magnitude = weight * Mathf.Pow(magnitude, exponent);
|
||||
// if (inverse)
|
||||
// magnitude = 1 / magnitude;
|
||||
// result += direction * magnitude;
|
||||
// }
|
||||
// if (average && this.synapses.Count > 0)
|
||||
// result /= this.synapses.Count + 1;
|
||||
|
||||
float d = Spherical.Distance(result, this.outputValue);
|
||||
if (d < 0.1f) {
|
||||
@ -143,8 +87,6 @@ public class Perceptoid : Neuroid {
|
||||
foreach (Receiver receiver in this.receivers)
|
||||
if (receiver.nucleus is Neuroid neuroid)
|
||||
neuroid.SetInput(this);
|
||||
//this.stale = 0;
|
||||
//this.Refresh();
|
||||
}
|
||||
|
||||
|
||||
@ -155,36 +97,4 @@ public class Perceptoid : Neuroid {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void ProcessStimulus(NanoBrainObj brain, int thingType, Vector3 localPosition) {
|
||||
Perceptoid selectedPerceptoid = null;
|
||||
foreach (Perceptoid nucleus in brain.perceptei) {
|
||||
if (nucleus is Perceptoid perceptoid && (thingType == 0 || perceptoid.receptor.thingType == thingType))
|
||||
if (selectedPerceptoid == null) {
|
||||
selectedPerceptoid = perceptoid;
|
||||
if (perceptoid.isSleeping) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (perceptoid.receptor.localPosition.magnitude < selectedPerceptoid.receptor.localPosition.magnitude)
|
||||
selectedPerceptoid = perceptoid;
|
||||
}
|
||||
if (selectedPerceptoid == null) {
|
||||
Debug.Log("No perceptoid selected, stimulus is ignored");
|
||||
return;
|
||||
}
|
||||
//selectedPerceptoid.receptor.position = localPosition;
|
||||
selectedPerceptoid.receptor.ProcessStimulus(888, localPosition);
|
||||
}
|
||||
|
||||
// public static Receptor GetReceptor(NanoBrainObj brain, int thingType) {
|
||||
// foreach (Perceptoid perceptoid in brain.perceptei) {
|
||||
// if (perceptoid.receptor != null) {
|
||||
// if (thingType == 0 || perceptoid.receptor.thingType == thingType)
|
||||
// return perceptoid.receptor;
|
||||
// }
|
||||
// }
|
||||
// Receptor receptor = new(thingType);
|
||||
// return receptor;
|
||||
// }
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ public class Receptor {
|
||||
/// </summary>
|
||||
public List<Perceptoid> perceptei = new();
|
||||
|
||||
//public int thingId;
|
||||
private int _thingType = 0;
|
||||
public int thingType {
|
||||
get { return _thingType; }
|
||||
@ -51,15 +50,16 @@ public class Receptor {
|
||||
selectedPerceptoid = perceptoid;
|
||||
// Do not look any further
|
||||
|
||||
// This does not do a lot....
|
||||
float deltaDistance = newLocalPosition.distance - previousLocalPosition.distance;
|
||||
// See if the change is significant
|
||||
AngleFloat deltaDirection = Direction.UnsignedAngle(newLocalPosition.direction, previousLocalPosition.direction);
|
||||
if (deltaDistance < this.distanceResolution && deltaDirection.inDegrees < directionResolution) {
|
||||
// The difference is not significant we don't process this data.
|
||||
this.localPosition = previousLocalPosition;
|
||||
return;
|
||||
}
|
||||
// // This does not do a lot....
|
||||
// float deltaDistance = newLocalPosition.distance - previousLocalPosition.distance;
|
||||
// // See if the change is significant
|
||||
// AngleFloat deltaDirection = Direction.UnsignedAngle(newLocalPosition.direction, previousLocalPosition.direction);
|
||||
// if (deltaDistance < this.distanceResolution && deltaDirection.inDegrees < directionResolution) {
|
||||
// // The difference is not significant we don't process this data.
|
||||
// this.localPosition = previousLocalPosition;
|
||||
// return;
|
||||
// }
|
||||
// This is now also handled by the UpdateState Spherical.Distance
|
||||
break;
|
||||
}
|
||||
else if (perceptoid.isSleeping) {
|
||||
|
||||
@ -1,136 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using LinearAlgebra;
|
||||
|
||||
// public class Receptor {
|
||||
|
||||
// public Neuroid neuroid;
|
||||
// public List<Perceptoid> perceptoids;
|
||||
|
||||
// public int thingId;
|
||||
// public int thingType;
|
||||
// public Vector3 localPosition;
|
||||
|
||||
// /// <summary>
|
||||
// /// Local position of the thing
|
||||
// /// </summary>
|
||||
// public virtual Vector3 position {
|
||||
// get {
|
||||
// return this.localPosition;
|
||||
// }
|
||||
// set {
|
||||
// this.localPosition = value;
|
||||
// neuroid.UpdateState();
|
||||
// }
|
||||
// }
|
||||
|
||||
// public virtual void ProcessStimulus(int thingId, Vector3 localPosition) {
|
||||
// this.thingId = thingId;
|
||||
// this.localPosition = localPosition;
|
||||
// neuroid.UpdateState();
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
public class SensoryNeuroid : Neuroid {
|
||||
// A neuroid which has no neurons as input
|
||||
// But receives value from a receptor
|
||||
public Receptor receptor;
|
||||
//public VelocityNeuroid velocityNeuroid;
|
||||
|
||||
public SensoryNeuroid(NanoBrainObj brain, int thingId, string name = "sensor") : base(brain, name) {
|
||||
this.name = name + ": position";
|
||||
// this.receptor = new Receptor(this) {
|
||||
// thingType = thingId
|
||||
// };
|
||||
// this.velocityNeuroid = new(brain, name + ": velocity");
|
||||
// // The velocity neuroid received position data from this
|
||||
// this.AddReceiver(velocityNeuroid);
|
||||
}
|
||||
|
||||
public void Replace(int thingId, string name = "sensor") {
|
||||
this.name = name + ": position";
|
||||
|
||||
this.receptor.thingType = thingId;
|
||||
this.receptor.localPosition = Spherical.zero;
|
||||
|
||||
this.outputValue = Spherical.zero;
|
||||
this.receivers = new();
|
||||
// this.AddReceiver(velocityNeuroid);
|
||||
|
||||
// // this.velocityNeuroid.name = name + ": velocity";
|
||||
// // this.velocityNeuroid.receivers = new();
|
||||
// this.velocityNeuroid.Replace(name + ": velocity");
|
||||
}
|
||||
|
||||
public override void UpdateState() {
|
||||
Vector3 result = receptor.localPosition.ToVector3();
|
||||
//foreach ((Nucleus nucleus, float weight) in this.synapses) {
|
||||
foreach (Synapse synapse in this.synapses) {
|
||||
Nucleus nucleus = synapse.nucleus;
|
||||
float weight = synapse.weight;
|
||||
Vector3 outputV3 = nucleus.outputValue.ToVector3();
|
||||
Vector3 direction = outputV3.normalized;
|
||||
float magnitude = outputV3.magnitude;
|
||||
|
||||
magnitude = weight * Mathf.Pow(magnitude, exponent);
|
||||
if (inverse)
|
||||
magnitude = 1 / magnitude;
|
||||
result += direction * magnitude;
|
||||
}
|
||||
if (average && this.synapses.Count > 0)
|
||||
result /= this.synapses.Count + 1;
|
||||
|
||||
this.outputValue = Spherical.FromVector3(result);
|
||||
//foreach (Neuroid neuroid in this.receivers)
|
||||
foreach (Receiver receiver in this.receivers)
|
||||
if (receiver.nucleus is Neuroid neuroid)
|
||||
neuroid.SetInput(this);
|
||||
//this.stale = 0;
|
||||
//this.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
// public class VelocityNeuroid : Neuroid {
|
||||
// // Would be best if this was received through a synapse via a loop....
|
||||
// private Vector3 lastPosition = Vector3.zero;
|
||||
// private float lastValueTime = 0;
|
||||
|
||||
// public VelocityNeuroid(NanoBrainObj net, string name = "velocity") : base(net, name) {
|
||||
// }
|
||||
|
||||
// public void Replace(string name = "velocity") {
|
||||
// this.name = name;
|
||||
// this.receivers = new();
|
||||
// this.lastPosition = Vector3.zero;
|
||||
// this.lastValueTime = 0;
|
||||
// }
|
||||
|
||||
// public override void UpdateState() {
|
||||
// // Assuming only one synapse for now....
|
||||
// //Vector3 currentPosition = this.synapses.First().Key.outputValue;
|
||||
// Spherical currentPosition = this.synapses.First().nucleus.outputValue;
|
||||
// Vector3 currentPositionV3 = currentPosition.ToVector3();
|
||||
// float currentValueTime = Time.time;
|
||||
|
||||
// if (lastValueTime != 0) {
|
||||
// float deltaTime = currentValueTime - lastValueTime;
|
||||
// Vector3 translation = currentPositionV3 - lastPosition;
|
||||
// Vector3 velocity = translation / deltaTime;
|
||||
|
||||
// // No activation function...
|
||||
// this.outputValue = Spherical.FromVector3(velocity);
|
||||
// //this.stale = 0;
|
||||
// //this.Refresh();
|
||||
|
||||
// foreach (Receiver receiver in receivers) {
|
||||
// if (receiver.nucleus is Neuroid neuroid)
|
||||
// neuroid.SetInput(this);
|
||||
// }
|
||||
// }
|
||||
|
||||
// this.lastValueTime = currentValueTime;
|
||||
// this.lastPosition = currentPositionV3;
|
||||
// }
|
||||
// }
|
||||
@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e34db6b23aa12477a2f98b9eb0cbbe2
|
||||
@ -296,18 +296,18 @@ public class GraphBoardView : VisualElement {
|
||||
|
||||
private void HandleMouseHover(Nucleus neuroid, Rect rect) {
|
||||
GUIContent tooltip;
|
||||
if (neuroid is SensoryNeuroid sensoryNeuroid) {
|
||||
tooltip = new(
|
||||
$"{sensoryNeuroid.name}" +
|
||||
$"\nThing {sensoryNeuroid.receptor.thingType}" +
|
||||
$"\nValue: {neuroid.outputValue}");
|
||||
}
|
||||
else {
|
||||
// if (neuroid is SensoryNeuroid sensoryNeuroid) {
|
||||
// tooltip = new(
|
||||
// $"{sensoryNeuroid.name}" +
|
||||
// $"\nThing {sensoryNeuroid.receptor.thingType}" +
|
||||
// $"\nValue: {neuroid.outputValue}");
|
||||
// }
|
||||
// else {
|
||||
tooltip = new(
|
||||
$"{neuroid.name}" +
|
||||
$"\nsynapse count {neuroid.synapses.Count}" +
|
||||
$"\nValue: {neuroid.outputValue}");
|
||||
}
|
||||
// }
|
||||
|
||||
Vector2 mousePosition = Event.current.mousePosition;
|
||||
|
||||
|
||||
@ -337,13 +337,14 @@ public class NanoBrainInspector : Editor {
|
||||
|
||||
private void HandleMouseHover(Nucleus nucleus, Rect rect) {
|
||||
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 SensoryNeuroid sensoryNeuroid) {
|
||||
// tooltip = new(
|
||||
// $"{sensoryNeuroid.name}" +
|
||||
// $"\nThing {sensoryNeuroid.receptor.thingType}" +
|
||||
// $"\nValue: {nucleus.outputValue}");
|
||||
// }
|
||||
//else
|
||||
if (nucleus is Perceptoid perceptoid) {
|
||||
if (perceptoid.receptor != null) {
|
||||
tooltip = new(
|
||||
$"{perceptoid.name}" +
|
||||
@ -396,7 +397,7 @@ public class NanoBrainInspector : Editor {
|
||||
|
||||
if (this.currentNucleus == null)
|
||||
return;
|
||||
|
||||
|
||||
this.currentNucleus.name = EditorGUILayout.TextField(this.currentNucleus.name);
|
||||
if (this.currentNucleus is Perceptoid currentPerceptoid) {
|
||||
currentPerceptoid.receptor.thingType = EditorGUILayout.IntField("Thing Type", currentPerceptoid.receptor.thingType);
|
||||
@ -572,29 +573,29 @@ public class NanoBrainInspector : Editor {
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnSceneGUI() {
|
||||
NanoBrain brain = target as NanoBrain;
|
||||
if (brain == null)
|
||||
return;
|
||||
// protected virtual void OnSceneGUI() {
|
||||
// NanoBrain brain = target as NanoBrain;
|
||||
// if (brain == null)
|
||||
// return;
|
||||
|
||||
Vector3 position = brain.transform.position;
|
||||
float radius = 1;
|
||||
// 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
|
||||
// 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);
|
||||
// // 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);
|
||||
}
|
||||
// // 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
|
||||
}
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d14e756f390f41a1c9923a0015329389
|
||||
@ -1,28 +0,0 @@
|
||||
// using System.Collections.Generic;
|
||||
// using UnityEngine;
|
||||
|
||||
// public class NucleusObj : ScriptableObject {
|
||||
// public virtual string objName { get; set; }
|
||||
|
||||
// public readonly Dictionary<NucleusObj, float> synapses = new();
|
||||
// public HashSet<NucleusObj> receivers = new();
|
||||
// public virtual Vector3 outputValue { get; set; }
|
||||
|
||||
// public int stale = 0;
|
||||
|
||||
// public NucleusObj(string name) {
|
||||
// this.objName = name;
|
||||
// }
|
||||
|
||||
// public virtual void AddReceiver(NucleusObj receiver) {
|
||||
// this.receivers.Add(receiver);
|
||||
// receiver.synapses[this] = 1.0f;
|
||||
// }
|
||||
|
||||
// public bool isSleeping {
|
||||
// get {
|
||||
// return this.stale > 2;
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca2a41cdae50b5005b5cf10cebb28de6
|
||||
Loading…
x
Reference in New Issue
Block a user