Initial nucleus array UI
This commit is contained in:
parent
4f2f230335
commit
394df2167d
@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
|
using static Unity.Mathematics.math;
|
||||||
|
|
||||||
public class Receptor : IReceptor {
|
public class Receptor : IReceptor {
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
@ -11,10 +12,23 @@ public class Receptor : IReceptor {
|
|||||||
set => _name = value;
|
set => _name = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Receiver {
|
||||||
|
public INucleus nucleus;
|
||||||
|
public int thingId;
|
||||||
|
public string thingName;
|
||||||
|
public Receiver(INucleus nucleus, int thingId, string thingName) {
|
||||||
|
this.nucleus = nucleus;
|
||||||
|
this.thingId = thingId;
|
||||||
|
this.thingName = thingName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[SerializeReference]
|
[SerializeReference]
|
||||||
private List<INucleus> _receivers = new();
|
private List<INucleus> _receivers = new();
|
||||||
public List<INucleus> receivers => _receivers;
|
public List<INucleus> receivers => _receivers;
|
||||||
|
|
||||||
|
protected int[] thingIds; // every receiver can handle a thing with this id
|
||||||
|
|
||||||
public virtual void AddReceiver(INucleus receivingNucleus) {
|
public virtual void AddReceiver(INucleus receivingNucleus) {
|
||||||
this.receivers.Add(receivingNucleus);
|
this.receivers.Add(receivingNucleus);
|
||||||
receivingNucleus.AddSynapse(this);
|
receivingNucleus.AddSynapse(this);
|
||||||
@ -25,7 +39,6 @@ public class Receptor : IReceptor {
|
|||||||
receiverNucleus.synapses.RemoveAll(synapse => synapse.nucleus == this);
|
receiverNucleus.synapses.RemoveAll(synapse => synapse.nucleus == this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//public bool isSleeping => false;
|
|
||||||
private int stale = 1000;
|
private int stale = 1000;
|
||||||
|
|
||||||
private bool _isSleeping = false;
|
private bool _isSleeping = false;
|
||||||
@ -42,7 +55,6 @@ public class Receptor : IReceptor {
|
|||||||
public float distanceResolution = 0.1f;
|
public float distanceResolution = 0.1f;
|
||||||
public float directionResolution = 5;
|
public float directionResolution = 5;
|
||||||
|
|
||||||
//public float3 outputValue => this.localPosition;
|
|
||||||
private float3 _outputValue;
|
private float3 _outputValue;
|
||||||
public float3 outputValue {
|
public float3 outputValue {
|
||||||
get { return this._outputValue; }
|
get { return this._outputValue; }
|
||||||
@ -53,6 +65,11 @@ public class Receptor : IReceptor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Receptor(Cluster cluster) {
|
||||||
|
if (cluster != null)
|
||||||
|
cluster.nuclei.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
public Receptor(Cluster cluster, INucleus nucleus) {
|
public Receptor(Cluster cluster, INucleus nucleus) {
|
||||||
if (cluster != null)
|
if (cluster != null)
|
||||||
cluster.nuclei.Add(this);
|
cluster.nuclei.Add(this);
|
||||||
@ -63,65 +80,67 @@ public class Receptor : IReceptor {
|
|||||||
if (cluster == null)
|
if (cluster == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
Receptor receptor = new(cluster);
|
||||||
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);
|
// Receptor receptor = new(cluster, nucleus);
|
||||||
return receptor;
|
// return receptor;
|
||||||
|
receptor.AddReceiver(nucleus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (receptor.receivers.Count == 0)
|
||||||
return null;
|
return null;
|
||||||
|
else
|
||||||
|
return receptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ProcessStimulus(int thingId, Vector3 newLocalPositionVector, string thingName = null) {
|
public virtual void ProcessStimulus(int thingId, Vector3 newLocalPositionVector, string thingName = null) {
|
||||||
this.localPosition = newLocalPositionVector;
|
this.localPosition = newLocalPositionVector;
|
||||||
|
|
||||||
|
thingIds ??= new int[this.receivers.Count];
|
||||||
|
|
||||||
|
int receiverIx = 0;
|
||||||
INucleus selectedReceiver = null;
|
INucleus selectedReceiver = null;
|
||||||
|
int selectedReceiverIx = 0;
|
||||||
foreach (INucleus receiver in this.receivers) {
|
foreach (INucleus receiver in this.receivers) {
|
||||||
|
// selectedReceiver = receiver;
|
||||||
|
// receiverIx++;
|
||||||
|
|
||||||
|
if (thingIds[receiverIx] == thingId) {
|
||||||
|
// We found an existing receiver for this thing
|
||||||
selectedReceiver = receiver;
|
selectedReceiver = receiver;
|
||||||
|
selectedReceiverIx = receiverIx;
|
||||||
|
// Do not look any further
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// selectedReceiver.thingId = thingId;
|
else if (receiver.isSleeping) {
|
||||||
|
// A sleeping receiver is not active and can therefore always be used
|
||||||
|
selectedReceiver = receiver;
|
||||||
|
selectedReceiverIx = receiverIx;
|
||||||
|
// Look further because we may find an existing receiver for this thing
|
||||||
|
}
|
||||||
|
else if (selectedReceiver == null) {
|
||||||
|
// If we haven't found a receiver yet, just start by taking the first
|
||||||
|
selectedReceiver = receiver;
|
||||||
|
selectedReceiverIx = receiverIx;
|
||||||
|
}
|
||||||
|
else if (selectedReceiver.isSleeping == false) {
|
||||||
|
// If no existing or sleeping receiver is found, we look for
|
||||||
|
// the receiver with the furthest/least interesting stimulus
|
||||||
|
if (length(receiver.outputValue) < length(selectedReceiver.outputValue)) {
|
||||||
|
// Debug.Log($"{selectedReceiver.name}[{selectedReceiverIx}] {length(selectedReceiver.outputValue)}" +
|
||||||
|
// $" {receiver.name}[{receiverIx}] {length(receiver.outputValue)} ");
|
||||||
|
selectedReceiver = receiver;
|
||||||
|
selectedReceiverIx = receiverIx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
receiverIx++;
|
||||||
|
}
|
||||||
|
// Debug.Log($"Receiver {selectedReceiver.name}[{selectedReceiverIx}] for thing {thingId}");
|
||||||
|
thingIds[selectedReceiverIx] = thingId;
|
||||||
// if (thingName != null)
|
// if (thingName != null)
|
||||||
// selectedReceiver.nucleus.name = selectedReceiver.nucleus.baseName + " " + thingName;
|
// selectedReceiver.nucleus.name = selectedReceiver.nucleus.baseName + " " + thingName;
|
||||||
selectedReceiver.UpdateState();
|
selectedReceiver.UpdateState();
|
||||||
|
|
||||||
// Perceptoid selectedPerceptoid = null;
|
|
||||||
// foreach (Perceptoid perceptoid in this.perceptei) {
|
|
||||||
// if (perceptoid.thingId == thingId) {
|
|
||||||
// // We found an existing perceptoid for this thing
|
|
||||||
// selectedPerceptoid = perceptoid;
|
|
||||||
// // Do not look any further
|
|
||||||
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// else if (perceptoid.isSleeping) {
|
|
||||||
// // A sleeping perceptoid is not active and can therefore always be reused
|
|
||||||
// selectedPerceptoid = perceptoid;
|
|
||||||
// // Look further because we could find a existing perceptoid for this thing
|
|
||||||
// }
|
|
||||||
|
|
||||||
// else if (selectedPerceptoid == null) {
|
|
||||||
// // If we haven't found a perceptoid yet, just start by taking the first
|
|
||||||
// selectedPerceptoid = perceptoid;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// else if (selectedPerceptoid.isSleeping == false) {
|
|
||||||
// // If no existing or sleeping perceptoid is found, we look for the perceptoid
|
|
||||||
// // we the furthest (least interesting) stimulus
|
|
||||||
// if (perceptoid.receptor.localPosition.magnitude < selectedPerceptoid.receptor.localPosition.magnitude) {
|
|
||||||
// Debug.Log($"{selectedPerceptoid.name} {selectedPerceptoid.receptor.localPosition.magnitude} {perceptoid.receptor.localPosition.magnitude} ");
|
|
||||||
// selectedPerceptoid = perceptoid;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (selectedPerceptoid == null) {
|
|
||||||
// Debug.Log("No perceptoid selected, stimulus is ignored");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// // Debug.Log($"Stimulus {thingType} {thingId} {selectedPerceptoid.name}");
|
|
||||||
// selectedPerceptoid.thingId = thingId;
|
|
||||||
// if (thingName != null)
|
|
||||||
// selectedPerceptoid.name = selectedPerceptoid.baseName + " " + thingName;
|
|
||||||
// selectedPerceptoid.UpdateState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateNuclei() {
|
public void UpdateNuclei() {
|
||||||
|
|||||||
@ -78,11 +78,12 @@ public class ClusterInspector : Editor {
|
|||||||
GameObject gameObject;
|
GameObject gameObject;
|
||||||
private List<NeuroidLayer> layers = new();
|
private List<NeuroidLayer> layers = new();
|
||||||
private readonly Dictionary<IReceptor, Vector2Int> neuroidPositions = new();
|
private readonly Dictionary<IReceptor, Vector2Int> neuroidPositions = new();
|
||||||
|
private bool expandArray = false;
|
||||||
|
|
||||||
Vector2 pan = Vector2.zero;
|
//Vector2 pan = Vector2.zero;
|
||||||
//float zoom = 1f;
|
//float zoom = 1f;
|
||||||
bool draggingCanvas = false;
|
//bool draggingCanvas = false;
|
||||||
Vector2 lastMouse;
|
//Vector2 lastMouse;
|
||||||
ClusterWrapper currentWrapper;
|
ClusterWrapper currentWrapper;
|
||||||
|
|
||||||
public GraphView() {
|
public GraphView() {
|
||||||
@ -98,9 +99,9 @@ public class ClusterInspector : Editor {
|
|||||||
Add(imguiContainer);
|
Add(imguiContainer);
|
||||||
|
|
||||||
//RegisterCallback<WheelEvent>(OnWheel);
|
//RegisterCallback<WheelEvent>(OnWheel);
|
||||||
RegisterCallback<MouseDownEvent>(OnMouseDown);
|
// RegisterCallback<MouseDownEvent>(OnMouseDown);
|
||||||
RegisterCallback<MouseMoveEvent>(OnMouseMove);
|
// RegisterCallback<MouseMoveEvent>(OnMouseMove);
|
||||||
RegisterCallback<MouseUpEvent>(OnMouseUp);
|
// RegisterCallback<MouseUpEvent>(OnMouseUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetGraph(GameObject gameObject, Cluster brain, INucleus nucleus, VisualElement inspectorContainer) {
|
public void SetGraph(GameObject gameObject, Cluster brain, INucleus nucleus, VisualElement inspectorContainer) {
|
||||||
@ -181,19 +182,19 @@ public class ClusterInspector : Editor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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(); }
|
||||||
}
|
// }
|
||||||
void OnMouseMove(MouseMoveEvent e) {
|
// void OnMouseMove(MouseMoveEvent e) {
|
||||||
if (draggingCanvas) {
|
// if (draggingCanvas) {
|
||||||
var delta = e.mousePosition - lastMouse;
|
// var delta = e.mousePosition - lastMouse;
|
||||||
pan += delta;
|
// pan += delta;
|
||||||
//content.style.left = pan.x;
|
// //content.style.left = pan.x;
|
||||||
//content.style.top = pan.y;
|
// //content.style.top = pan.y;
|
||||||
lastMouse = e.mousePosition;
|
// lastMouse = e.mousePosition;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
void OnMouseUp(MouseUpEvent e) { if (e.button == 2) draggingCanvas = false; }
|
// void OnMouseUp(MouseUpEvent e) { if (e.button == 2) draggingCanvas = false; }
|
||||||
|
|
||||||
void OnIMGUI() {
|
void OnIMGUI() {
|
||||||
if (currentNucleus == null)
|
if (currentNucleus == null)
|
||||||
@ -217,9 +218,24 @@ public class ClusterInspector : Editor {
|
|||||||
|
|
||||||
// Draw selected Nucleus
|
// Draw selected Nucleus
|
||||||
Handles.color = Color.white;
|
Handles.color = Color.white;
|
||||||
|
if (expandArray) {
|
||||||
|
float spacing = 400f / this.currentNucleus.array.nuclei.Length;
|
||||||
|
float margin = 10 + spacing / 2;
|
||||||
|
int row = 0;
|
||||||
|
foreach (INucleus nucleus in this.currentNucleus.array.nuclei) {
|
||||||
|
Vector3 pos = new(150, margin + row * spacing, 0.0f);
|
||||||
|
Handles.color = Color.white;
|
||||||
|
//Handles.DrawLine(parentPos, pos);
|
||||||
|
|
||||||
|
DrawNucleus(nucleus, pos, 0, size);
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
Handles.DrawSolidDisc(position, Vector3.forward, size + 2);
|
Handles.DrawSolidDisc(position, Vector3.forward, size + 2);
|
||||||
DrawNucleus(this.currentNucleus, position, length(this.currentNucleus.outputValue), 20);
|
DrawNucleus(this.currentNucleus, position, length(this.currentNucleus.outputValue), 20);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawReceivers(INucleus nucleus, Vector3 parentPos, float size) {
|
private void DrawReceivers(INucleus nucleus, Vector3 parentPos, float size) {
|
||||||
int nodeCount = nucleus.receivers.Count;
|
int nodeCount = nucleus.receivers.Count;
|
||||||
@ -318,18 +334,36 @@ public class ClusterInspector : Editor {
|
|||||||
normal = { textColor = Color.white },
|
normal = { textColor = Color.white },
|
||||||
fontStyle = FontStyle.Bold,
|
fontStyle = FontStyle.Bold,
|
||||||
};
|
};
|
||||||
if (nucleus is Neuron neuron) {
|
if (nucleus is INucleus neuron) {
|
||||||
if (neuron.array == null || neuron.array.nuclei == null || neuron.array.nuclei.Length == 0)
|
if (neuron.array == null || neuron.array.nuclei == null || neuron.array.nuclei.Length == 0)
|
||||||
neuron.array = new NucleusArray(neuron);
|
neuron.array = new NucleusArray(neuron);
|
||||||
|
|
||||||
if (neuron.array.nuclei.Length > 1) {
|
if ((!expandArray || neuron.array.nuclei[0] != this.currentNucleus) && neuron.array.nuclei.Length > 1) {
|
||||||
Handles.Label(labelPosition, neuron.array.nuclei.Length.ToString(), style);
|
Handles.Label(labelPosition, neuron.array.nuclei.Length.ToString(), style);
|
||||||
}
|
}
|
||||||
|
style.alignment = TextAnchor.UpperCenter;
|
||||||
|
Vector3 labelPos = position - Vector3.down * (size + 0.2f); // below disc along up axis
|
||||||
|
// if ((!expandArray || neuron.array.nuclei[0] != this.currentNucleus) && neuron.array.nuclei.Length > 1) {
|
||||||
|
// Handles.Label(labelPos, nucleus.name, style);
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
if (expandArray && neuron.array.nuclei[0] == this.currentNucleus) {
|
||||||
|
int arrayIx = 0;
|
||||||
|
foreach (INucleus n in neuron.array.nuclei) {
|
||||||
|
if (n == neuron)
|
||||||
|
break;
|
||||||
|
arrayIx++;
|
||||||
}
|
}
|
||||||
|
Handles.Label(labelPos, $"{nucleus.name}[{arrayIx}]", style);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Handles.Label(labelPos, nucleus.name, style);
|
||||||
|
}
|
||||||
|
else {
|
||||||
style.alignment = TextAnchor.UpperCenter;
|
style.alignment = TextAnchor.UpperCenter;
|
||||||
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
|
||||||
Handles.Label(labelPos, nucleus.name, style);
|
Handles.Label(labelPos, nucleus.name, style);
|
||||||
|
}
|
||||||
|
|
||||||
Rect neuronRect = new(position.x - size, position.y - size, size * 2, size * 2);
|
Rect neuronRect = new(position.x - size, position.y - size, size * 2, size * 2);
|
||||||
int id = GUIUtility.GetControlID(FocusType.Passive);
|
int id = GUIUtility.GetControlID(FocusType.Passive);
|
||||||
@ -371,7 +405,13 @@ public class ClusterInspector : Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void HandleClicked(IReceptor nucleus) {
|
private void HandleClicked(IReceptor nucleus) {
|
||||||
|
if (nucleus == this.currentNucleus) {
|
||||||
if (nucleus is INucleus n) {
|
if (nucleus is INucleus n) {
|
||||||
|
expandArray = !expandArray;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (nucleus is INucleus n) {
|
||||||
this.currentNucleus = n;
|
this.currentNucleus = n;
|
||||||
BuildLayers();
|
BuildLayers();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user