using System; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using static CommunicationEvents; public class FactManager : MonoBehaviour { public GameObject SmartMenu; private List<int> NextEmpties = new List<int>(); // Start is called before the first frame update void Start() { //We dont want to have this here anymore... //CommunicationEvents.RemoveFactEvent.AddListener(DeleteFact); NextEmpties.Add(0); } // Update is called once per frame void Update() { } public static bool findFact(Fact search, out Fact found) { foreach (Fact f in CommunicationEvents.Facts) { if (f.GetType() == search.GetType() && f.Equivalent(search)) { found = f; return true; } } found = search; return false; } public static void addFact(int id, Fact fact) { CommunicationEvents.Facts.Insert(id, fact); //TODO (alt): insert in MMT if needed here/ on Invoke() //TODO: remove Inovkes() elsewhere CommunicationEvents.AddFactEvent.Invoke(fact); } public static Fact AddFactIfNotFound(int id, Fact fact, out bool exists) { if (exists = findFact(fact, out Fact res)) { //TODO: del 'fact' in MMT (alt.: s.TODO in addFact) return res; } else { addFact(id, fact); return fact; } } public PointFact AddPointFact(RaycastHit hit, int id) { return (PointFact) AddFactIfNotFound(id, new PointFact(id, hit.point, hit.normal), out bool obsolete); } public PointFact AddPointFact(int id, Vector3 point, Vector3 normal) { return (PointFact) AddFactIfNotFound(id, new PointFact(id, point, normal), out bool obsolete); } public OnLineFact AddOnLineFact(int pid, int lid, int id) { return (OnLineFact)AddFactIfNotFound(id, new OnLineFact(id, pid, lid), out bool obsolete); } public LineFact AddLineFact(int pid1, int pid2, int id) { return (LineFact)AddFactIfNotFound(id, new LineFact(id, pid1, pid2), out bool obsolete); } public RayFact AddRayFact(int pid1, int pid2, int id) { RayFact rayFact = (RayFact)AddFactIfNotFound(id, new RayFact(id, pid1, pid2), out bool exists); if (exists) return rayFact; //Add all PointFacts on Ray as OnLineFacts PointFact rayP1 = (PointFact)Facts[rayFact.Pid1]; int layerMask = LayerMask.GetMask("Point"); RaycastHit[] hitsA = Physics.RaycastAll(rayP1.Point, rayFact.Dir, Mathf.Infinity, layerMask); RaycastHit[] hitsB = Physics.RaycastAll(rayP1.Point, -rayFact.Dir, Mathf.Infinity, layerMask); void AddHitIfOnLine(RaycastHit hit) { if (Math3d.IsPointApproximatelyOnLine(rayP1.Point, rayFact.Dir, hit.transform.position)) { AddOnLineFact(hit.transform.gameObject.GetComponent<FactObject>().Id, rayFact.Id, GetFirstEmptyID()); } } foreach (RaycastHit hit in hitsA) AddHitIfOnLine(hit); foreach (RaycastHit hit in hitsB) AddHitIfOnLine(hit); return rayFact; } public AngleFact AddAngleFact(int pid1, int pid2, int pid3, int id) { return (AngleFact)AddFactIfNotFound(id, new AngleFact(id, pid1, pid2, pid3), out bool obsolete); } public void DeleteFact(Fact fact) { if (Facts.Contains(fact)) { NextEmpties.Add(fact.Id); //Facts.RemoveAt(fact.Id); Facts.Remove(Facts.Find(x => x.Id == fact.Id)); CommunicationEvents.RemoveFactEvent.Invoke(fact); } } public int GetFirstEmptyID() { NextEmpties.Sort(); int id = NextEmpties[0]; NextEmpties.RemoveAt(0); if (NextEmpties.Count == 0) NextEmpties.Add(id + 1); Debug.Log("place fact at " + id); return id; } }