using Newtonsoft.Json; using System; using System.Collections.Generic; using UnityEditor; using UnityEngine; using XRLib; namespace Studio.VirtualFactory { public class AGVMap : MonoBehaviour, ISingle { public List nodes = new(); #if UNITY_EDITOR public void OnDrawGizmos() { HashSet<(Vector3, Vector3)> drawnLines = new HashSet<(Vector3, Vector3)>(); foreach (var n in nodes) { if (n == null) continue; Handles.Label(n.transform.position + Vector3.up * 0.5f, n.name); foreach (var l in n.linkedNodes) { Vector3 start = n.transform.position; if (l == null) continue; Vector3 end = l.transform.position; // Ensure the line is always stored in a consistent order var line = start.x < end.x || (start.x == end.x && start.y < end.y) || (start.x == end.x && start.y == end.y && start.z < end.z) ? (start, end) : (end, start); if (!drawnLines.Contains(line)) { Gizmos.DrawLine(start, end); drawnLines.Add(line); } } } } #endif public List GetPortNodes() { var result = new List(); foreach(var n in nodes) { if (n is AGVPortNode pn) { result.Add(pn); } } return result; } public bool TryGetEmptyInputPortNode(out AGVPortNode portNode) { foreach (var n in nodes) { if (n is not AGVPortNode pn) continue; if (pn.portType != AGVPortNode.PortType.Input) continue; if (pn.loader is not InputPort) continue; Debug.Log($"TryGetEmptyInputPortNode: {pn.name}"); if (pn.loader.isEmpty) { portNode = pn; return true; } } portNode = null; return false; } internal List FindPath(AGVNode startNode, AGVNode targetNode) { var visited = new HashSet(); var path = new List(); if (DFS(startNode, targetNode, visited, path)) { return path; } return null; // °æ·Î¸¦ ãÀ» ¼ö ¾øÀ½ } private bool DFS(AGVNode current, AGVNode target, HashSet visited, List path) { visited.Add(current); path.Add(current); if (current == target) { return true; } foreach (var neighbor in current.linkedNodes) { if (neighbor == null || visited.Contains(neighbor)) continue; if (DFS(neighbor, target, visited, path)) { return true; } } path.RemoveAt(path.Count - 1); return false; } } }