From e568759d405e960019395f4a8e960c5ac68f236e Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Wed, 14 Jan 2026 21:37:04 +0100 Subject: [PATCH] improved synapse coloring --- Assembly-CSharp.csproj | 1 + Assets/NanoBrain/Scene.meta | 8 + Assets/NanoBrain/Scene/TestScene.unity | 487 ++++++++++++++++++ Assets/NanoBrain/Scene/TestScene.unity.meta | 7 + .../VisualEditor/Editor/ClusterInspector.cs | 29 +- .../Editor/NanoBrainComponent_Editor.cs | 32 +- .../VisualEditor/NanoBrainComponent.cs | 10 +- .../Boids/Prefabs/Stationary Boid.prefab | 87 ++++ .../Boids/Prefabs/Stationary Boid.prefab.meta | 7 + Assets/Scenes/Boids/Scripts/Boid.cs | 4 +- Assets/Scenes/Boids/Scripts/StationaryBoid.cs | 75 +++ .../Boids/Scripts/StationaryBoid.cs.meta | 7 + 12 files changed, 738 insertions(+), 16 deletions(-) create mode 100644 Assets/NanoBrain/Scene.meta create mode 100644 Assets/NanoBrain/Scene/TestScene.unity create mode 100644 Assets/NanoBrain/Scene/TestScene.unity.meta create mode 100644 Assets/Scenes/Boids/Prefabs/Stationary Boid.prefab create mode 100644 Assets/Scenes/Boids/Prefabs/Stationary Boid.prefab.meta create mode 100644 Assets/Scenes/Boids/Scripts/StationaryBoid.cs create mode 100644 Assets/Scenes/Boids/Scripts/StationaryBoid.cs.meta diff --git a/Assembly-CSharp.csproj b/Assembly-CSharp.csproj index 771999b..4ac4a55 100644 --- a/Assembly-CSharp.csproj +++ b/Assembly-CSharp.csproj @@ -69,6 +69,7 @@ + diff --git a/Assets/NanoBrain/Scene.meta b/Assets/NanoBrain/Scene.meta new file mode 100644 index 0000000..d71b5e5 --- /dev/null +++ b/Assets/NanoBrain/Scene.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bfd7dadd61c0891d8a94db0196e61a8a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NanoBrain/Scene/TestScene.unity b/Assets/NanoBrain/Scene/TestScene.unity new file mode 100644 index 0000000..d852af4 --- /dev/null +++ b/Assets/NanoBrain/Scene/TestScene.unity @@ -0,0 +1,487 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 10 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 13 + m_BakeOnSceneLoad: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 2 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 1 + m_PVRFilteringGaussRadiusAO: 1 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1001 &551770709 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalPosition.x + value: -1.00054 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalPosition.y + value: -1.02912 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalPosition.z + value: 0.82188 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093763, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_Name + value: Boid2 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} +--- !u!1 &968074744 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 968074747} + - component: {fileID: 968074746} + - component: {fileID: 968074745} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &968074745 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 968074744} + m_Enabled: 1 +--- !u!20 &968074746 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 968074744} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &968074747 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 968074744} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1342149740 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1342149742} + - component: {fileID: 1342149741} + m_Layer: 0 + m_Name: SwamControl + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1342149741 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1342149740} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0464906885ae3494f8fd0314719fb2db, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::SwarmControl + speed: 0.5 + inertia: 0.1 + alignmentForce: 0 + cohesionForce: 10 + separationForce: 5 + avoidanceForce: 5 + separationDistance: 0.5 + perceptionDistance: 1 + spaceSize: {x: 10, y: 10, z: 10} + boundaryWidth: {x: 1, y: 1, z: 1} +--- !u!4 &1342149742 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1342149740} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -1.00377, y: -1.02283, z: 0.72231} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2011285159 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2011285161} + - component: {fileID: 2011285160} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &2011285160 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2011285159} + m_Enabled: 1 + serializedVersion: 12 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize2D: {x: 0.5, y: 0.5} + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 + m_ForceVisible: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 + m_LightUnit: 1 + m_LuxAtDistance: 1 + m_EnableSpotReflector: 1 +--- !u!4 &2011285161 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2011285159} + serializedVersion: 2 + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1001 &4573752827112804207 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093762, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7761516481062093763, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} + propertyPath: m_Name + value: Boid1 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 6860355b30724b5ddb35781dcaf3b57e, type: 3} +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 968074747} + - {fileID: 2011285161} + - {fileID: 4573752827112804207} + - {fileID: 551770709} + - {fileID: 1342149742} diff --git a/Assets/NanoBrain/Scene/TestScene.unity.meta b/Assets/NanoBrain/Scene/TestScene.unity.meta new file mode 100644 index 0000000..676153c --- /dev/null +++ b/Assets/NanoBrain/Scene/TestScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1070383882ed0f5379a3b34e8ccb1f75 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs b/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs index d33435b..072d8c1 100644 --- a/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs +++ b/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs @@ -196,7 +196,7 @@ public class ClusterInspector : Editor { // } // void OnMouseUp(MouseUpEvent e) { if (e.button == 2) draggingCanvas = false; } - void OnIMGUI() { + public void OnIMGUI() { if (currentNucleus == null) return; @@ -313,7 +313,8 @@ public class ClusterInspector : Editor { drawnArrays.Add(neuroid.array); } - float value = length(synapse.nucleus.outputValue); + float value = length(synapse.nucleus.outputValue) * synapse.weight; + // Debug.Log($"{synapse.nucleus.name}: {value} {length(synapse.nucleus.outputValue)} {synapse.weight}"); if (value > maxValue) maxValue = value; neuronCount++; @@ -334,23 +335,37 @@ public class ClusterInspector : Editor { Vector3 pos = new(250, margin + row * spacing, 0.0f); Handles.color = Color.white; Handles.DrawLine(parentPos, pos); - if (synapse.nucleus != null) - DrawNucleus(synapse.nucleus, pos, maxValue, size); + if (synapse.nucleus != null) { + Color color = Color.black; + if (synapse.nucleus.isSleeping) + color = Color.darkRed; + else if (Application.isPlaying) { + float brightness = length(synapse.nucleus.outputValue) * synapse.weight / maxValue; + color = new Color(brightness, brightness, brightness, 1f); + } + DrawNucleus(synapse.nucleus, pos, maxValue, size, color); + } row++; } } private void DrawNucleus(IReceptor nucleus, Vector3 position, float maxValue, float size) { + Color color; if (nucleus.isSleeping) - Handles.color = Color.darkRed; + color = Color.darkRed; else { if (Application.isPlaying) { float brightness = length(nucleus.outputValue) / maxValue; - Handles.color = new Color(brightness, brightness, brightness, 1f); + color = new Color(brightness, brightness, brightness, 1f); } else - Handles.color = Color.black; + color = Color.black; } + DrawNucleus(nucleus, position, maxValue, size, color); + } + + private void DrawNucleus(IReceptor nucleus, Vector3 position, float maxValue, float size, Color color) { + Handles.color = color; Handles.DrawSolidDisc(position, Vector3.forward, size); Handles.color = Color.white; diff --git a/Assets/NanoBrain/VisualEditor/Editor/NanoBrainComponent_Editor.cs b/Assets/NanoBrain/VisualEditor/Editor/NanoBrainComponent_Editor.cs index 6da496b..c9ad194 100644 --- a/Assets/NanoBrain/VisualEditor/Editor/NanoBrainComponent_Editor.cs +++ b/Assets/NanoBrain/VisualEditor/Editor/NanoBrainComponent_Editor.cs @@ -11,11 +11,14 @@ public class NanoBrainComponent_Editor : Editor { protected NanoBrainComponent component; private SerializedProperty brainProp; + ClusterInspector.GraphView board; + public void OnEnable() { component = target as NanoBrainComponent; if (Application.isPlaying == false) brainProp = serializedObject.FindProperty(nameof(NanoBrainComponent.defaultBrain)); + } public override VisualElement CreateInspectorGUI() { @@ -52,9 +55,9 @@ public class NanoBrainComponent_Editor : Editor { minHeight = 500, } }; - ClusterInspector.GraphView board; board = new ClusterInspector.GraphView(); board.style.flexGrow = 1; + mainContainer.Add(board); inspectorContainer = new VisualElement { name = "inspector", @@ -63,7 +66,6 @@ public class NanoBrainComponent_Editor : Editor { } }; - mainContainer.Add(board); mainContainer.Add(inspectorContainer); root.Add(mainContainer); @@ -76,7 +78,7 @@ public class NanoBrainComponent_Editor : Editor { UpdateLayout(evt.newRect.width); }); - if (brain != null) + if (brain != null && board != null) board.SetGraph(component.gameObject, brain, brain.output, inspectorContainer); // else // Debug.LogWarning(" No brain!"); @@ -86,6 +88,30 @@ public class NanoBrainComponent_Editor : Editor { return root; } + // void OnSceneGUI() { + // if (Application.isPlaying && board != null) + // board.OnIMGUI(); + // } + + void OnSceneGui(SceneView sv) { + if (Application.isPlaying == false) + return; + // May need some throttling here... + if (board != null) { + Debug.Log("."); + board.OnIMGUI(); + } + + // EditorApplication.delayCall = UpdateInspectorUI; + } + + void UpdateInspectorUI() { + if (board != null) { + Debug.Log("."); + board.OnIMGUI(); + } + } + private void UpdateLayout(float containerWidth) { if (containerWidth > 800f) { mainContainer.style.flexDirection = FlexDirection.Row; diff --git a/Assets/NanoBrain/VisualEditor/NanoBrainComponent.cs b/Assets/NanoBrain/VisualEditor/NanoBrainComponent.cs index 475e1a0..09fbfaa 100644 --- a/Assets/NanoBrain/VisualEditor/NanoBrainComponent.cs +++ b/Assets/NanoBrain/VisualEditor/NanoBrainComponent.cs @@ -12,10 +12,12 @@ public class NanoBrainComponent : MonoBehaviour { brainInstance.name = defaultBrain.name + " (Instance)"; SwarmControl sc = FindFirstObjectByType(); - UpdateWeight(brainInstance, "Avoidance", sc.avoidanceForce); - UpdateWeight(brainInstance, "Cohesion", sc.cohesionForce); - UpdateWeight(brainInstance, "Separation", sc.separationForce); - UpdateWeight(brainInstance, "Alignment", sc.alignmentForce); + if (sc != null) { + UpdateWeight(brainInstance, "Avoidance", sc.avoidanceForce); + UpdateWeight(brainInstance, "Cohesion", sc.cohesionForce); + UpdateWeight(brainInstance, "Separation", sc.separationForce); + UpdateWeight(brainInstance, "Alignment", sc.alignmentForce); + } } return brainInstance; } diff --git a/Assets/Scenes/Boids/Prefabs/Stationary Boid.prefab b/Assets/Scenes/Boids/Prefabs/Stationary Boid.prefab new file mode 100644 index 0000000..b45e904 --- /dev/null +++ b/Assets/Scenes/Boids/Prefabs/Stationary Boid.prefab @@ -0,0 +1,87 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &1401715754342779814 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 8702527964058765412, guid: f9c706268554ce449a8773675b2864b8, type: 3} + propertyPath: m_LocalPosition.x + value: -1.00054 + objectReference: {fileID: 0} + - target: {fileID: 8702527964058765412, guid: f9c706268554ce449a8773675b2864b8, type: 3} + propertyPath: m_LocalPosition.y + value: -1.02912 + objectReference: {fileID: 0} + - target: {fileID: 8702527964058765412, guid: f9c706268554ce449a8773675b2864b8, type: 3} + propertyPath: m_LocalPosition.z + value: 0.82188 + objectReference: {fileID: 0} + - target: {fileID: 8702527964058765412, guid: f9c706268554ce449a8773675b2864b8, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 8702527964058765412, guid: f9c706268554ce449a8773675b2864b8, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8702527964058765412, guid: f9c706268554ce449a8773675b2864b8, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8702527964058765412, guid: f9c706268554ce449a8773675b2864b8, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8702527964058765412, guid: f9c706268554ce449a8773675b2864b8, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8702527964058765412, guid: f9c706268554ce449a8773675b2864b8, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8702527964058765412, guid: f9c706268554ce449a8773675b2864b8, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8702527964058765413, guid: f9c706268554ce449a8773675b2864b8, type: 3} + propertyPath: m_Name + value: Boid1 Variant + objectReference: {fileID: 0} + m_RemovedComponents: + - {fileID: 9169912378811971808, guid: f9c706268554ce449a8773675b2864b8, type: 3} + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 8702527964058765413, guid: f9c706268554ce449a8773675b2864b8, type: 3} + insertIndex: -1 + addedObject: {fileID: 8788086714463777302} + m_SourcePrefab: {fileID: 100100000, guid: f9c706268554ce449a8773675b2864b8, type: 3} +--- !u!1 &7761516481062093763 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 8702527964058765413, guid: f9c706268554ce449a8773675b2864b8, type: 3} + m_PrefabInstance: {fileID: 1401715754342779814} + m_PrefabAsset: {fileID: 0} +--- !u!114 &8788086714463777302 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7761516481062093763} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c156ab45bfd15d213b1be7451d0c0151, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::StationaryBoid + sc: {fileID: 0} + velocity: {x: 0, y: 0, z: 0} + acceleration: {x: 0, y: 0, z: 0} + nanoBrain: {fileID: 0} + id: 0 + red: {fileID: 2100000, guid: 2a7557e54580b6a8b976f12aa6cc761c, type: 2} + gray: {fileID: 2100000, guid: a79ccc131cb43254cb8575d1cedb537e, type: 2} diff --git a/Assets/Scenes/Boids/Prefabs/Stationary Boid.prefab.meta b/Assets/Scenes/Boids/Prefabs/Stationary Boid.prefab.meta new file mode 100644 index 0000000..ea903ab --- /dev/null +++ b/Assets/Scenes/Boids/Prefabs/Stationary Boid.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6860355b30724b5ddb35781dcaf3b57e +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Boids/Scripts/Boid.cs b/Assets/Scenes/Boids/Scripts/Boid.cs index a3f81d3..5c99655 100644 --- a/Assets/Scenes/Boids/Scripts/Boid.cs +++ b/Assets/Scenes/Boids/Scripts/Boid.cs @@ -11,7 +11,7 @@ public class Boid : MonoBehaviour { public Vector3 velocity = Vector3.zero; public Vector3 acceleration = Vector3.zero; - private Bounds innerBounds; + protected Bounds innerBounds; public NanoBrainComponent nanoBrain; public Receptor boundaryReceptor; @@ -41,7 +41,7 @@ public class Boid : MonoBehaviour { innerBounds = new(sc.transform.position, sc.spaceSize - 2 * sc.boundaryWidth); } - void Update() { + protected virtual void Update() { Collider[] results = Physics.OverlapSphere(this.transform.position, sc.perceptionDistance); foreach (Collider c in results) { if (c as CapsuleCollider != null) { diff --git a/Assets/Scenes/Boids/Scripts/StationaryBoid.cs b/Assets/Scenes/Boids/Scripts/StationaryBoid.cs new file mode 100644 index 0000000..a8e3031 --- /dev/null +++ b/Assets/Scenes/Boids/Scripts/StationaryBoid.cs @@ -0,0 +1,75 @@ +using UnityEngine; + +public class StationaryBoid : Boid +{ + protected override void Update() + { + Collider[] results = Physics.OverlapSphere(this.transform.position, sc.perceptionDistance); + foreach (Collider c in results) + { + if (c as CapsuleCollider != null) + { + Boid neighbour = c.GetComponentInParent(); + if (neighbour == null || neighbour == this) + continue; + + int thingId = neighbour.GetInstanceID(); + + 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) + boidReceptor?.ProcessStimulus(thingId, localPosition, neighbour.name); + + Vector3 localVelocity = this.transform.InverseTransformVector(neighbour.velocity); + if (localVelocity.sqrMagnitude > 0) + boidVelocityReceptor?.ProcessStimulus(thingId, localVelocity); + } + } + + if (!innerBounds.Contains(this.transform.position)) + { + Vector3 point = this.transform.position; + Vector3 pointOnBounds = innerBounds.ClosestPoint(point); + Vector3 desiredWorldSpace = (pointOnBounds - point).normalized * sc.speed; + Vector3 desiredLocalSpace = -this.transform.InverseTransformPoint(desiredWorldSpace); + boundaryReceptor.ProcessStimulus(777, desiredLocalSpace); + } + + Vector3 worldForce = this.transform.TransformDirection(nanoBrain.root.outputValue); + + this.velocity = (1 - sc.inertia) * (worldForce * Time.deltaTime) + sc.inertia * velocity; + if (this.velocity.magnitude > 0) + this.velocity = this.velocity.normalized * sc.speed; + else + this.velocity = this.transform.forward * sc.speed; + //Debug.DrawRay(this.transform.position, this.velocity, Color.blue); + + // this.transform.position += this.velocity * Time.deltaTime; + + // if (this.velocity != Vector3.zero) + // { + // Quaternion targetRotation = Quaternion.LookRotation(this.velocity); + // transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 5f); // Adjust the speed of rotation + // } + + nanoBrain.brain.UpdateNuclei(); + + // Renderer renderer = GetComponentInChildren(); + // results = Physics.OverlapSphere(this.transform.position, 0.1f); + // if (results.Length > 1) { + // // string s= this.name; + // // foreach (Collider c in results) + // // s += " " + c.transform.parent.gameObject.name; + // // Debug.Log(s); + // renderer.sharedMaterial = red; + // } + // else { + // renderer.sharedMaterial = gray; + // } + } + +} \ No newline at end of file diff --git a/Assets/Scenes/Boids/Scripts/StationaryBoid.cs.meta b/Assets/Scenes/Boids/Scripts/StationaryBoid.cs.meta new file mode 100644 index 0000000..b06bf2e --- /dev/null +++ b/Assets/Scenes/Boids/Scripts/StationaryBoid.cs.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c156ab45bfd15d213b1be7451d0c0151 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: