///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // D E R E L I C T // /// // (c) 2003..2025 using Godot; using gdcoll = Godot.Collections; //using System.Linq; [Tool, GlobalClass] public partial class AStarGraph : Resource { [Export] public gdcoll.Array Points { get; set; } = new(); [Export] public gdcoll.Array> Connections { get; set; } = new(); private int _nextId = 0; public int AddPoint( Vector3 position ) { var id = _nextId++; if( Points.Count <= _nextId ) { Points.Resize( _nextId ); Connections.Resize( _nextId ); } Points[id] = position; Connections[id] = new gdcoll.Array(); return id; } public void ConnectPoints( int idFrom, int idTo, bool bidirectional = true ) { //if (!Points.ContainsKey(idFrom) || !Points.ContainsKey(idTo)) return; //if (!Connections.ContainsKey(idFrom)) Connections[idFrom] = new(); Connections[idFrom].Add( idTo ); if( bidirectional ) { //if (!Connections.ContainsKey(idTo)) Connections[idTo] = new(); Connections[idTo].Add( idFrom ); } } public bool ArePointsConnected( int idFrom, int idTo ) { return Connections[idFrom].Contains( idTo ); } public int GetAvailablePointId() => _nextId++; public Vector3 GetPointPosition( int id ) => Points[id]; public gdcoll.Array GetPointConnections( int id ) => Connections[id]; //public int[] GetPointIds() => Points.Keys.ToArray(); public int GetClosestPoint( Vector3 position ) { int closestId = -1; float closestDistSq = float.MaxValue; int curId = 0; foreach( var pos in Points ) { if( !pos.IsFinite() ) continue; float distSq = position.DistanceSquaredTo( pos ); if( distSq < closestDistSq ) { if( Connections[curId].Count > 0 ) { closestDistSq = distSq; closestId = curId; } else { Points[curId] = Vector3.Inf; } } curId++; } return closestId; } public void Clear() { Points.Clear(); Connections.Clear(); _nextId = 0; } }