Separation/Cohesion curve

This commit is contained in:
Pascal Serrarens 2025-12-17 09:28:34 +01:00
parent 76af037a01
commit 0cee652110
4 changed files with 2611 additions and 35 deletions

View File

@ -2,6 +2,46 @@ using UnityEngine;
[System.Serializable] [System.Serializable]
public class Neuroid : Nucleus { public class Neuroid : Nucleus {
public enum CurvePresets {
Linear,
Power,
Sqrt,
Reciprocal,
Custom
}
[SerializeField]
private CurvePresets _curvePreset;
public CurvePresets curvePreset {
get { return _curvePreset; }
set {
_curvePreset = value;
this.curve = GenerateCurve();
}
}
public AnimationCurve curve;
public float curveMax = 1.0f;
public AnimationCurve GenerateCurve() {
switch (this.curvePreset) {
case CurvePresets.Linear:
this.curveMax = 1;
return Synapse.Presets.Linear(1);
case CurvePresets.Power:
this.curveMax = 1;
return Synapse.Presets.Power(2.0f, 1);
case CurvePresets.Sqrt:
this.curveMax = 1;
return Synapse.Presets.Power(0.5f, 1);
case CurvePresets.Reciprocal:
this.curveMax = 1 / 0.01f * 1;
return Synapse.Presets.Reciprocal(1);
default:
this.curveMax = 1;
//return AnimationCurve.Constant(0, 1, 1);
return this.curve;
}
}
public bool average = false; public bool average = false;
public bool inverse = false; public bool inverse = false;
public float exponent = 1.0f; public float exponent = 1.0f;
@ -16,7 +56,7 @@ public class Neuroid : Nucleus {
Debug.LogError("No neuroid network"); Debug.LogError("No neuroid network");
} }
public Neuroid(string name): base(name) {} public Neuroid(string name) : base(name) { }
public void SetWeight(Neuroid input, float weight) { public void SetWeight(Neuroid input, float weight) {
this.SetWeight((Nucleus)input, weight); this.SetWeight((Nucleus)input, weight);
@ -40,17 +80,18 @@ public class Neuroid : Nucleus {
Vector3 result = Vector3.zero; Vector3 result = Vector3.zero;
//foreach ((Nucleus nucleus, float weight) in this.synapses) { //foreach ((Nucleus nucleus, float weight) in this.synapses) {
foreach (Synapse synapse in this.synapses) { foreach (Synapse synapse in this.synapses) {
Nucleus nucleus = synapse.nucleus; Nucleus synapseNucleus = synapse.nucleus;
if (nucleus is Neuroid neuroid && neuroid.isSleeping) if (synapseNucleus is Neuroid neuroid && neuroid.isSleeping)
continue; continue;
Vector3 direction = nucleus.outputValue.normalized; Vector3 direction = synapseNucleus.outputValue.normalized;
float magnitude = nucleus.outputValue.magnitude; float magnitude = synapseNucleus.outputValue.magnitude;
float weight = synapse.weight; float weight = synapse.weight;
magnitude = weight * Mathf.Pow(magnitude, exponent); magnitude = weight * curve.Evaluate(synapseNucleus.outputValue.magnitude);
if (inverse && magnitude > 0) // magnitude = weight * Mathf.Pow(magnitude, exponent);
magnitude = 1 / magnitude; // if (inverse && magnitude > 0)
// magnitude = 1 / magnitude;
result += direction * magnitude; result += direction * magnitude;
} }

View File

@ -73,7 +73,7 @@ public class NanoBrainComponent_Editor : Editor {
}); });
if (brain != null) if (brain != null)
board.SetGraph(brain, brain.root, inspectorContainer); board.SetGraph(component.gameObject, brain, brain.root, inspectorContainer);
// else // else
// Debug.LogWarning(" No brain!"); // Debug.LogWarning(" No brain!");

View File

@ -63,7 +63,7 @@ public class NanoBrainInspector : Editor {
}); });
if (brain != null) if (brain != null)
board.SetGraph(brain, brain.root, inspectorContainer); board.SetGraph(null, brain, brain.root, inspectorContainer);
else else
Debug.LogWarning(" No brain!"); Debug.LogWarning(" No brain!");
@ -75,6 +75,7 @@ public class NanoBrainInspector : Editor {
NanoBrainObj brain; NanoBrainObj brain;
SerializedObject serializedBrain; SerializedObject serializedBrain;
Nucleus currentNucleus; Nucleus currentNucleus;
GameObject gameObject;
private List<NeuroidLayer> layers = new(); private List<NeuroidLayer> layers = new();
private readonly Dictionary<Nucleus, Vector2Int> neuroidPositions = new(); private readonly Dictionary<Nucleus, Vector2Int> neuroidPositions = new();
@ -102,7 +103,8 @@ public class NanoBrainInspector : Editor {
RegisterCallback<MouseUpEvent>(OnMouseUp); RegisterCallback<MouseUpEvent>(OnMouseUp);
} }
public void SetGraph(NanoBrainObj brain, Nucleus nucleus, VisualElement inspectorContainer) { public void SetGraph(GameObject gameObject, NanoBrainObj brain, Nucleus nucleus, VisualElement inspectorContainer) {
this.gameObject = gameObject;
this.brain = brain; this.brain = brain;
if (Application.isPlaying == false) if (Application.isPlaying == false)
this.serializedBrain = new SerializedObject(brain); this.serializedBrain = new SerializedObject(brain);
@ -398,31 +400,45 @@ public class NanoBrainInspector : Editor {
this.currentNucleus.name = EditorGUILayout.TextField(this.currentNucleus.name); this.currentNucleus.name = EditorGUILayout.TextField(this.currentNucleus.name);
if (this.currentNucleus is Perceptoid currentPerceptoid) if (this.currentNucleus is Perceptoid currentPerceptoid)
currentPerceptoid.thingType = EditorGUILayout.IntField("Thing Type", currentPerceptoid.thingType); currentPerceptoid.thingType = EditorGUILayout.IntField("Thing Type", currentPerceptoid.thingType);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Output Value", GUILayout.Width(100));
EditorGUILayout.Vector3Field(GUIContent.none, this.currentNucleus.outputValue);
EditorGUILayout.EndHorizontal();
if (this.currentNucleus.synapses.Count > 0) {
if (this.currentNucleus is Neuroid 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));
EditorGUILayout.EndHorizontal();
}
if (Application.isPlaying)
EditorGUILayout.FloatField("Output", this.currentNucleus.outputValue.magnitude);
else
EditorGUILayout.LabelField(" ");
if (this.currentNucleus.synapses.Count > 0) {
foreach (Synapse synapse in this.currentNucleus.synapses) { foreach (Synapse synapse in this.currentNucleus.synapses) {
if (synapse.nucleus != null) { if (synapse.nucleus != null) {
EditorGUILayout.Space();
EditorGUI.BeginDisabledGroup(synapse.nucleus.isSleeping); EditorGUI.BeginDisabledGroup(synapse.nucleus.isSleeping);
EditorGUILayout.BeginHorizontal(); if (Application.isPlaying)
EditorGUILayout.LabelField(synapse.nucleus.name, GUILayout.Width(150)); EditorGUILayout.FloatField(synapse.nucleus.name, synapse.nucleus.outputValue.magnitude * synapse.weight);
EditorGUILayout.Vector3Field(GUIContent.none, synapse.nucleus.outputValue); //, GUILayout.Width(180)); else
EditorGUILayout.EndHorizontal(); EditorGUILayout.LabelField(synapse.nucleus.name);
EditorGUI.indentLevel++; EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck(); // 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); // synapse.curvePreset = (Synapse.CurvePresets)EditorGUILayout.EnumPopup("Preset", synapse.curvePreset);
if (EditorGUI.EndChangeCheck()) { // if (EditorGUI.EndChangeCheck()) {
synapse.curve = synapse.GenerateCurve(); // synapse.curve = synapse.GenerateCurve();
} // }
if (synapse.curveMax > 0) // if (synapse.curveMax > 0)
EditorGUILayout.CurveField("Curve", synapse.curve, Color.cyan, new Rect(0, 0, 1, synapse.curveMax)); // EditorGUILayout.CurveField("Curve", synapse.curve, Color.cyan, new Rect(0, 0, 1, synapse.curveMax));
else // else
EditorGUILayout.CurveField("Curve", synapse.curve, Color.cyan, new Rect(0, synapse.curveMax, 1, -synapse.curveMax)); // EditorGUILayout.CurveField("Curve", synapse.curve, Color.cyan, new Rect(0, synapse.curveMax, 1, -synapse.curveMax));
EditorGUI.indentLevel--; EditorGUI.indentLevel--;
EditorGUI.EndDisabledGroup(); EditorGUI.EndDisabledGroup();
} }
@ -438,6 +454,11 @@ public class NanoBrainInspector : Editor {
ConnectNucleus(this.currentNucleus); ConnectNucleus(this.currentNucleus);
DisconnectNucleus(this.currentNucleus); DisconnectNucleus(this.currentNucleus);
if (this.gameObject != null) {
Vector3 worldVector = this.gameObject.transform.TransformVector(this.currentNucleus.outputValue);
Debug.DrawRay(this.gameObject.transform.position, worldVector, Color.yellow );
}
}); });
inspectorContainer.Add(container); inspectorContainer.Add(container);

File diff suppressed because it is too large Load Diff