93 lines
3.9 KiB
C#
93 lines
3.9 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using LinearAlgebra;
|
|
|
|
public class Receptor {
|
|
/// <summary>
|
|
/// The list of perceptoid which can process stimuli from this receptor
|
|
/// </summary>
|
|
public List<Perceptoid> perceptei = new();
|
|
|
|
private int _thingType = 0;
|
|
public int thingType {
|
|
get { return _thingType; }
|
|
set {
|
|
_thingType = value;
|
|
foreach (Perceptoid perceptoid in perceptei) {
|
|
perceptoid.thingType = _thingType;
|
|
}
|
|
}
|
|
}
|
|
public Vector3 localPosition;
|
|
public float distanceResolution = 0.1f;
|
|
public float directionResolution = 5;
|
|
|
|
public Receptor(NanoBrainObj brain, int thingType) {
|
|
this.thingType = thingType;
|
|
//this.perceptei.Add(perceptoid);
|
|
brain.receptors.Add(this);
|
|
}
|
|
|
|
public static Receptor GetReceptor(NanoBrainObj brain, int thingType) {
|
|
foreach (Receptor receptor in brain.receptors) {
|
|
if (thingType == 0 || receptor.thingType == thingType)
|
|
return receptor;
|
|
}
|
|
Receptor newReceptor = new(brain, thingType);
|
|
return newReceptor;
|
|
}
|
|
|
|
public virtual void ProcessStimulus(int thingId, Vector3 newLocalPositionVector) {
|
|
//Spherical newLocalPosition = Spherical.FromVector3(newLocalPositionVector);
|
|
|
|
Vector3 previousLocalPosition = this.localPosition;
|
|
this.localPosition = newLocalPositionVector;
|
|
|
|
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
|
|
|
|
// // 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) {
|
|
// 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;
|
|
selectedPerceptoid.UpdateState();
|
|
}
|
|
} |