Move to Spherical outputvalue

This commit is contained in:
Pascal Serrarens 2025-12-23 09:19:05 +01:00
parent 65359ecbfa
commit a500a9e16e
21 changed files with 805 additions and 626 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -54,7 +54,7 @@ public class NanoBrain_Editor : Editor {
DrawGraph();
EditorGUILayout.TextField("Name", currentNucleus.name);
EditorGUILayout.Vector3Field("Output Value", currentNucleus.outputValue);
EditorGUILayout.Vector3Field("Output Value", currentNucleus.outputValue.ToVector3());
if (currentNucleus.synapses.Count > 0) {
EditorGUI.indentLevel++;
//foreach ((Nucleus nucleus, float weight) in currentNucleus.synapses) {
@ -65,7 +65,7 @@ public class NanoBrain_Editor : Editor {
EditorGUI.BeginDisabledGroup(nucleus.isSleeping);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.Vector3Field(nucleus.name, nucleus.outputValue);
EditorGUILayout.Vector3Field(nucleus.name, nucleus.outputValue.ToVector3());
EditorGUILayout.FloatField(weight, GUILayout.Width(50));
EditorGUILayout.EndHorizontal();
@ -265,7 +265,7 @@ public class NanoBrain_Editor : Editor {
// 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);
Vector3 worldForce = brain.transform.TransformDirection(this.currentNucleus.outputValue.ToVector3());
//Debug.DrawRay(position, worldForce * 10, Color.yellow);
Handles.DrawLine(position, position + worldForce * 10);
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b011ef22eaa3add3591b513363fbbd0a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,12 @@
{
"folders": [
{
"path": "../.."
},
{
"name": "LinearAlgebra-csharp",
"path": "LinearAlgebra-csharp"
}
],
"settings": {}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: cfec45da5945b94d684a763d86b0dcf8
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,4 +1,5 @@
using UnityEngine;
using LinearAlgebra;
[System.Serializable]
public class Neuroid : Nucleus {
@ -37,7 +38,6 @@ public class Neuroid : Nucleus {
return Synapse.Presets.Reciprocal(1);
default:
this.curveMax = 1;
//return AnimationCurve.Constant(0, 1, 1);
return this.curve;
}
}
@ -63,42 +63,34 @@ public class Neuroid : Nucleus {
}
public void SetInput(Neuroid input) {
// if (this.synapses.ContainsKey(input) == false)
// this.synapses[input] = 1.0f;
if (this.SynapseExists(input) == false)
this.SetWeight(input, 1.0f);
UpdateState();
}
public void SetInput(Neuroid input, float weight) {
//this.synapses[input] = weight;
this.SetWeight(input, weight);
UpdateState();
}
public virtual void UpdateState() {
Vector3 result = Vector3.zero;
//foreach ((Nucleus nucleus, float weight) in this.synapses) {
foreach (Synapse synapse in this.synapses) {
Nucleus synapseNucleus = synapse.nucleus;
if (synapseNucleus is Neuroid neuroid && neuroid.isSleeping)
continue;
Vector3 direction = synapseNucleus.outputValue.normalized;
float magnitude = synapseNucleus.outputValue.magnitude;
Vector3 direction = synapseNucleus.outputValue.direction.ToVector3();
float weight = synapse.weight;
magnitude = weight * curve.Evaluate(synapseNucleus.outputValue.magnitude);
// magnitude = weight * Mathf.Pow(magnitude, exponent);
// if (inverse && magnitude > 0)
// magnitude = 1 / magnitude;
result += direction * magnitude;
float magnitude = weight * curve.Evaluate(synapseNucleus.outputValue.magnitude);
result += direction * magnitude;
}
if (average && this.synapses.Count > 0)
result /= this.synapses.Count;
this.outputValue = result;
this.outputValue = Spherical.FromVector3(result);
this.stale = 0;
foreach (Receiver receiver in this.receivers) {
@ -107,8 +99,5 @@ public class Neuroid : Nucleus {
}
}
// public bool IsStale() {
// return this.stale > 2;
// }
}

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using LinearAlgebra;
[System.Serializable]
public class Nucleus {
@ -63,7 +64,7 @@ public class Nucleus {
public NanoBrainObj brain { get; set; }
public virtual Vector3 outputValue { get; set; }
public virtual Spherical outputValue { get; set; }
[System.NonSerialized]
public int stale = 0;

View File

@ -1,4 +1,5 @@
using UnityEngine;
using LinearAlgebra;
[System.Serializable]
public class Perceptoid : Neuroid {
@ -88,9 +89,9 @@ public class Perceptoid : Neuroid {
this.thingType = thingType;
this.receptor.thingType = thingType;
this.receptor.localPosition = Vector3.zero;
this.receptor.localPosition = Spherical.zero;
this.outputValue = Vector3.zero;
this.outputValue = Spherical.zero;
this.receivers = new();
this.AddReceiver(velocityNeuroid);
@ -98,11 +99,11 @@ public class Perceptoid : Neuroid {
}
public override void UpdateState() {
Vector3 result = receptor.localPosition;
Vector3 result = receptor.localPosition.ToVector3();
foreach (Synapse synapse in this.synapses) {
Nucleus nucleus = synapse.nucleus;
float weight = synapse.weight;
Vector3 direction = nucleus.outputValue.normalized;
Vector3 direction = nucleus.outputValue.normalized.ToVector3();
float magnitude = nucleus.outputValue.magnitude;
magnitude = weight * Mathf.Pow(magnitude, exponent);
@ -113,16 +114,16 @@ public class Perceptoid : Neuroid {
if (average && this.synapses.Count > 0)
result /= this.synapses.Count + 1;
this.outputValue = result;
this.outputValue = Spherical.FromVector3(result);
foreach (Receiver receiver in this.receivers)
if (receiver.nucleus is Neuroid neuroid)
neuroid.SetInput(this);
this.stale = 0;
}
public void UpdateState(int thingId, Vector3 receptorValue) {
public void UpdateState(int thingId, Spherical receptorValue) {
this.thingId = thingId;
Vector3 result = receptorValue;
Spherical result = receptorValue;
// foreach (Synapse synapse in this.synapses) {
// Nucleus nucleus = synapse.nucleus;
// float weight = synapse.weight;

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using LinearAlgebra;
public class Receptor {
@ -9,7 +10,7 @@ public class Receptor {
public int thingId;
public int thingType;
public Vector3 localPosition;
public Spherical localPosition;
public Receptor(Perceptoid perceptoid) {
this.perceptei.Add(perceptoid);
@ -18,7 +19,7 @@ public class Receptor {
public virtual void ProcessStimulus(int thingId, Vector3 localPosition) {
this.thingId = thingId;
this.localPosition = localPosition;
this.localPosition = Spherical.FromVector3(localPosition);
Perceptoid selectedPerceptoid = null;
foreach (Perceptoid perceptoid in this.perceptei) {

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using LinearAlgebra;
// public class Receptor {
@ -52,9 +53,9 @@ public class SensoryNeuroid : Neuroid {
this.name = name + ": position";
this.receptor.thingType = thingId;
this.receptor.localPosition = Vector3.zero;
this.receptor.localPosition = Spherical.zero;
this.outputValue = Vector3.zero;
this.outputValue = Spherical.zero;
this.receivers = new();
this.AddReceiver(velocityNeuroid);
@ -64,13 +65,14 @@ public class SensoryNeuroid : Neuroid {
}
public override void UpdateState() {
Vector3 result = receptor.localPosition;
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 direction = nucleus.outputValue.normalized;
float magnitude = nucleus.outputValue.magnitude;
Vector3 outputV3 = nucleus.outputValue.ToVector3();
Vector3 direction = outputV3.normalized;
float magnitude = outputV3.magnitude;
magnitude = weight * Mathf.Pow(magnitude, exponent);
if (inverse)
@ -80,7 +82,7 @@ public class SensoryNeuroid : Neuroid {
if (average && this.synapses.Count > 0)
result /= this.synapses.Count + 1;
this.outputValue = result;
this.outputValue = Spherical.FromVector3(result);
//foreach (Neuroid neuroid in this.receivers)
foreach (Receiver receiver in this.receivers)
if (receiver.nucleus is Neuroid neuroid)
@ -107,16 +109,17 @@ public class VelocityNeuroid : Neuroid {
public override void UpdateState() {
// Assuming only one synapse for now....
//Vector3 currentPosition = this.synapses.First().Key.outputValue;
Vector3 currentPosition = this.synapses.First().nucleus.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 = currentPosition - lastPosition;
Vector3 translation = currentPositionV3 - lastPosition;
Vector3 velocity = translation / deltaTime;
// No activation function...
this.outputValue = velocity;
this.outputValue = Spherical.FromVector3(velocity);
this.stale = 0;
//foreach (Neuroid receiver in receivers)
@ -127,6 +130,6 @@ public class VelocityNeuroid : Neuroid {
}
this.lastValueTime = currentValueTime;
this.lastPosition = currentPosition;
this.lastPosition = currentPositionV3;
}
}

View File

@ -341,7 +341,7 @@ public class GraphBoardView : VisualElement {
currentNucleus.name = EditorGUILayout.TextField(currentNucleus.name);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Output Value", GUILayout.Width(100));
EditorGUILayout.Vector3Field(GUIContent.none, currentNucleus.outputValue);
EditorGUILayout.Vector3Field(GUIContent.none, currentNucleus.outputValue.ToVector3());
EditorGUILayout.EndHorizontal();
if (currentNucleus.synapses.Count > 0) {
EditorGUILayout.LabelField("Synapses");
@ -360,7 +360,7 @@ public class GraphBoardView : VisualElement {
// currentNucleus.synapses[nucleus] = EditorGUILayout.FloatField(weight, GUILayout.Width(40));
synapse.weight = EditorGUILayout.FloatField(synapse.weight, GUILayout.Width(40));
EditorGUI.indentLevel++;
EditorGUILayout.Vector3Field(GUIContent.none, synapse.nucleus.outputValue, GUILayout.Width(180));
EditorGUILayout.Vector3Field(GUIContent.none, synapse.nucleus.outputValue.ToVector3(), GUILayout.Width(180));
EditorGUILayout.EndHorizontal();
EditorGUI.EndDisabledGroup();

View File

@ -455,7 +455,7 @@ public class NanoBrainInspector : Editor {
DisconnectNucleus(this.currentNucleus);
if (this.gameObject != null) {
Vector3 worldVector = this.gameObject.transform.TransformVector(this.currentNucleus.outputValue);
Vector3 worldVector = this.gameObject.transform.TransformVector(this.currentNucleus.outputValue.ToVector3());
Debug.DrawRay(this.gameObject.transform.position, worldVector, Color.yellow);
}
});

View File

@ -1,5 +1,6 @@
using System.Collections.Generic;
using UnityEngine;
using LinearAlgebra;
[CreateAssetMenu(menuName = "Passer/NanoBrain")]
public class NanoBrainObj : ScriptableObject, ISerializationCallbackReceiver {
@ -33,12 +34,12 @@ public class NanoBrainObj : ScriptableObject, ISerializationCallbackReceiver {
foreach (Nucleus nucleus in nuclei) {
nucleus.stale++;
if (nucleus.isSleeping)
nucleus.outputValue = Vector3.zero;
nucleus.outputValue = Spherical.zero;
}
foreach (Perceptoid perception in perceptei) {
perception.stale++;
if (perception.isSleeping)
perception.outputValue = Vector3.zero;
perception.outputValue = Spherical.zero;
}
}

View File

@ -55,7 +55,7 @@ public class Boid : MonoBehaviour {
boundaryReceptor.ProcessStimulus(777, desiredLocalSpace);
}
Vector3 worldForce = this.transform.TransformDirection(nanoBrain.root.outputValue);
Vector3 worldForce = this.transform.TransformDirection(nanoBrain.root.outputValue.ToVector3());
this.velocity = (1 - sc.inertia) * (worldForce * Time.deltaTime) + sc.inertia * velocity;
if (this.velocity.magnitude > 0)

View File

@ -1,4 +1,5 @@
using UnityEngine;
using LinearAlgebra;
public class Swarming : Nucleus {
public Neuroid cohesion;
@ -8,7 +9,7 @@ public class Swarming : Nucleus {
public Neuroid output;
public override Vector3 outputValue { get => output.outputValue; set => output.outputValue = value; }
public override Spherical outputValue { get => output.outputValue; set => output.outputValue = value; }
public Swarming(NanoBrainObj brain, Perception perception, SwarmControl sc) : base("Swarming Nucleus") {
this.cohesion = new(brain, "Cohesion") { inverse = false };

View File

@ -4,13 +4,14 @@
"com.unity.collab-proxy": "2.10.2",
"com.unity.ide.rider": "3.0.38",
"com.unity.ide.visualstudio": "2.0.25",
"com.unity.inputsystem": "1.14.2",
"com.unity.multiplayer.center": "1.0.0",
"com.unity.render-pipelines.universal": "17.2.0",
"com.unity.inputsystem": "1.17.0",
"com.unity.multiplayer.center": "1.0.1",
"com.unity.render-pipelines.universal": "17.3.0",
"com.unity.test-framework": "1.6.0",
"com.unity.timeline": "1.8.9",
"com.unity.ugui": "2.0.0",
"com.unity.modules.accessibility": "1.0.0",
"com.unity.modules.adaptiveperformance": "1.0.0",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0",
@ -37,6 +38,7 @@
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vectorgraphics": "1.0.0",
"com.unity.modules.vehicles": "1.0.0",
"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",

View File

@ -10,7 +10,7 @@
"url": "https://packages.unity.com"
},
"com.unity.burst": {
"version": "1.8.25",
"version": "1.8.26",
"depth": 2,
"source": "registry",
"dependencies": {
@ -33,8 +33,8 @@
"dependencies": {
"com.unity.burst": "1.8.23",
"com.unity.mathematics": "1.3.2",
"com.unity.nuget.mono-cecil": "1.11.5",
"com.unity.test-framework": "1.4.6",
"com.unity.nuget.mono-cecil": "1.11.5",
"com.unity.test-framework.performance": "3.0.3"
},
"url": "https://packages.unity.com"
@ -64,7 +64,7 @@
"url": "https://packages.unity.com"
},
"com.unity.inputsystem": {
"version": "1.14.2",
"version": "1.17.0",
"depth": 0,
"source": "registry",
"dependencies": {
@ -73,14 +73,14 @@
"url": "https://packages.unity.com"
},
"com.unity.mathematics": {
"version": "1.3.2",
"version": "1.3.3",
"depth": 2,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.multiplayer.center": {
"version": "1.0.0",
"version": "1.0.1",
"depth": 0,
"source": "builtin",
"dependencies": {
@ -88,14 +88,14 @@
}
},
"com.unity.nuget.mono-cecil": {
"version": "1.11.5",
"version": "1.11.6",
"depth": 3,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.render-pipelines.core": {
"version": "17.2.0",
"version": "17.3.0",
"depth": 1,
"source": "builtin",
"dependencies": {
@ -105,17 +105,16 @@
"com.unity.collections": "2.4.3",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.rendering.light-transport": "1.0.1"
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.render-pipelines.universal": {
"version": "17.2.0",
"version": "17.3.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.render-pipelines.core": "17.2.0",
"com.unity.shadergraph": "17.2.0",
"com.unity.render-pipelines.core": "17.3.0",
"com.unity.shadergraph": "17.3.0",
"com.unity.render-pipelines.universal-config": "17.0.3"
}
},
@ -127,29 +126,19 @@
"com.unity.render-pipelines.core": "17.0.3"
}
},
"com.unity.rendering.light-transport": {
"version": "1.0.1",
"depth": 2,
"source": "builtin",
"dependencies": {
"com.unity.collections": "2.2.0",
"com.unity.mathematics": "1.2.4",
"com.unity.modules.terrain": "1.0.0"
}
},
"com.unity.searcher": {
"version": "4.9.3",
"version": "4.9.4",
"depth": 2,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.shadergraph": {
"version": "17.2.0",
"version": "17.3.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.render-pipelines.core": "17.2.0",
"com.unity.render-pipelines.core": "17.3.0",
"com.unity.searcher": "4.9.3"
}
},
@ -178,9 +167,9 @@
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0"
},
"url": "https://packages.unity.com"
@ -200,6 +189,14 @@
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.adaptiveperformance": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.subsystems": "1.0.0"
}
},
"com.unity.modules.ai": {
"version": "1.0.0",
"depth": 0,
@ -407,6 +404,16 @@
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.vectorgraphics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.modules.vehicles": {
"version": "1.0.0",
"depth": 0,

View File

@ -58,7 +58,9 @@ GraphicsSettings:
m_FogKeepExp2: 1
m_AlbedoSwatchInfos: []
m_RenderPipelineGlobalSettingsMap:
UnityEngine.Rendering.Universal.UniversalRenderPipeline: {fileID: 11400000, guid: 370d27fa5af5291e18529fa336759ac9, type: 2}
UnityEngine.Rendering.Universal.UniversalRenderPipeline: {fileID: 11400000, guid: 2acc6984d25d4a508a6d7042927d3083, type: 2}
m_ShaderBuildSettings:
keywordDeclarationOverrides: []
m_LightsUseLinearIntensity: 1
m_LightsUseColorTemperature: 1
m_LogWhenShaderIsCompiled: 0

View File

@ -0,0 +1,17 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 53
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 15023, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier: UnityEditor.MultiplayerModule.dll::UnityEditor.Multiplayer.Internal.MultiplayerRolesSettings
m_MultiplayerRoleForClassicProfile:
m_Keys: []
m_Values:

View File

@ -1,2 +1,2 @@
m_EditorVersion: 6000.2.13f1
m_EditorVersionWithRevision: 6000.2.13f1 (abdb44fca7f7)
m_EditorVersion: 6000.3.2f1
m_EditorVersionWithRevision: 6000.3.2f1 (a9779f353c9b)