Skip to content
Snippets Groups Projects
FactSpawner.cs 13.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • using System.Collections;
    using System.Collections.Generic;
    
    using static CommunicationEvents;
    
    
    public class FactSpawner : MonoBehaviour
    {
    
    mariuskern's avatar
    mariuskern committed
            TestPoint,
    
            AddFactEvent.AddListener(SpawnFactRepresentation);
    
            AnimateNonExistingFactEvent.AddListener(AnimateNonExistingFactTrigger);
    
            StartT0Event.AddListener(AnimateFunctionCalls);
        }
    
        private void OnDisable()
        {
            AddFactEvent.RemoveListener(SpawnFactRepresentation);
            AnimateNonExistingFactEvent.RemoveListener(AnimateNonExistingFactTrigger);
            StartT0Event.RemoveListener(AnimateFunctionCalls);
    
        public void SpawnFactRepresentation(Fact fact)
    
                case PointFact PointFact:
                    SpawnPoint(PointFact); break;
    
    mariuskern's avatar
    mariuskern committed
                case TestPointFact TestPointFact:
                    SpawnTestPoint(TestPointFact); break;
    
                case LineFact LineFact:
                    SpawnLine(LineFact); break;
    
                //case RightAngleFact AngleFact: //needed for Hint System
                case AbstractAngleFact AngleFact:
    
                    SpawnAngle(AngleFact); break;
                case RayFact RayFact:
                    SpawnRay(RayFact); break;
                case CircleFact CircleFact:
                    SpawnRingAndCircle(CircleFact); break;
    
                case QuadFact QuadFact:
                    SpawnQuad(QuadFact); break;
    
                case TriangleFact TrisFact:
                    SpawnTris(TrisFact); break;
    
                case ConeVolumeFact ConeVolumeFact:
                    SpawnCone(ConeVolumeFact); break;
                case TruncatedConeVolumeFact TruncatedConeVolumeFact:
                    SpawnTruncatedCone(TruncatedConeVolumeFact); break;
    
                case RectangleFact rectangleFact:
                    SpawnRectangle(rectangleFact); break;
    
    MaZiFAU's avatar
    MaZiFAU committed
    
    
        public void SpawnRectangle(RectangleFact fact){
    
    Paul-Walcher's avatar
    Paul-Walcher committed
    
    
            GameObject rectangle = GameObject.Instantiate(Rectangle);
    
    Paul-Walcher's avatar
    Paul-Walcher committed
    
    
            rectangle.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
            rectangle.transform.localScale = Vector3.Scale(rectangle.transform.localScale, fact.LocalScale);
            rectangle.GetComponentInChildren<TextMeshPro>().text = fact.GetLabel(StageStatic.stage.factState) + " = " + System.Math.Round(fact.Area, 2) + "m²";
    
    Paul-Walcher's avatar
    Paul-Walcher committed
        }
    
    
        public void SpawnPoint(PointFact fact)
        {
    
            GameObject point = GameObject.Instantiate(Sphere);
    
    MaZiFAU's avatar
    MaZiFAU committed
            fact.WorldRepresentation = point.GetComponent<FactObject3D>();
    
            fact.WorldRepresentation.Fact = fact;
    
    
            point.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
    
    mariuskern's avatar
    mariuskern committed
        public void SpawnTestPoint(TestPointFact fact)
        {
            GameObject point = GameObject.Instantiate(TestPoint);
            fact.WorldRepresentation = point.GetComponent<FactObject3D>();
            fact.WorldRepresentation.Fact = fact;
    
            point.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
        }
    
    
            GameObject line = GameObject.Instantiate(Line);
    
    MaZiFAU's avatar
    MaZiFAU committed
            fact.WorldRepresentation = line.GetComponentInChildren<FactObject3D>();
    
            fact.WorldRepresentation.Fact = fact;
    
    
            line.transform.position = fact.Position;
    
    MaZiFAU's avatar
    MaZiFAU committed
            //Change scale and rotation, so that the two points are connected by the line
            //and without affecting Scale of the Text
    
            line.transform.GetChild(0).localScale = fact.LocalScale;
            line.transform.GetChild(0).rotation = fact.Rotation;
    
    MaZiFAU's avatar
    MaZiFAU committed
            line.GetComponentInChildren<TextMeshPro>().text =
    
                fact.GetLabel(StageStatic.stage.factState) + " = " + System.Math.Round(fact.Distance, 2) + " m";
    
            GameObject line = GameObject.Instantiate(Ray);
    
    MaZiFAU's avatar
    MaZiFAU committed
            fact.WorldRepresentation = line.GetComponentInChildren<FactObject3D>();
    
            fact.WorldRepresentation.Fact = fact;
    
    
            //Place the Line in the centre of the two points
    
            line.transform.position = fact.Position;
    
    MaZiFAU's avatar
    MaZiFAU committed
            //Change scale and rotation, so that the two points are connected by the line
            //and without affecting Scale of the Text
    
            line.transform.GetChild(0).localScale = fact.LocalScale;
            line.transform.GetChild(0).rotation = fact.Rotation;
    
    MaZiFAU's avatar
    MaZiFAU committed
    
    
        //Spawn an angle: point with id = angleFact.Pid2 is the point where the angle gets applied
    
        public void SpawnAngle(AbstractAngleFact fact)
    
        {
            //Change FactRepresentation to Angle
    
            GameObject angle = GameObject.Instantiate(Angle);
    
    MaZiFAU's avatar
    MaZiFAU committed
            fact.WorldRepresentation = angle.GetComponentInChildren<FactObject3D>();
    
            fact.WorldRepresentation.Fact = fact;
    
    
    MaZiFAU's avatar
    MaZiFAU committed
            angle.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
    
            TextMeshPro[] texts = angle.GetComponentsInChildren<TextMeshPro>();
    
    MaZiFAU's avatar
    MaZiFAU committed
            foreach (TextMeshPro t in texts)
            {
                //Change Text not to the id, but to the angle-value (from both sides)
    
                t.text = System.Math.Round((float)fact.angle, 2) + "°";
    
            CircleSegmentGenerator[] segments = angle.GetComponentsInChildren<CircleSegmentGenerator>();
            foreach (CircleSegmentGenerator c in segments)
    
    MaZiFAU's avatar
    MaZiFAU committed
                c.setAngle((float)fact.angle);
    
        public void SpawnRingAndCircle(CircleFact fact)
    
            var ringAndCircleGO = new GameObject("RingAndCircle");
    
            SpawnRing(fact, ringAndCircleGO.transform);
            SpawnCircle(fact, ringAndCircleGO.transform);
    
            ringAndCircleGO.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
    
    MaZiFAU's avatar
    MaZiFAU committed
            fact.WorldRepresentation = ringAndCircleGO.AddComponent<FactObject3D>();
    
            fact.WorldRepresentation.Fact = fact;
    
    MaZiFAU's avatar
    MaZiFAU committed
        public void SpawnRing(CircleFact circleFact, Transform parent = null)
    
    MaZiFAU's avatar
    MaZiFAU committed
            GameObject ring = GameObject.Instantiate(Ring, parent);
    
            TorusGenerator[] tori = ring.GetComponentsInChildren<TorusGenerator>();
    
            foreach (var torus in tori)
    
    MaZiFAU's avatar
    MaZiFAU committed
                torus.torusRadius = circleFact.radius + (float)Math3d.vectorPrecission;
    
    MaZiFAU's avatar
    MaZiFAU committed
        public void SpawnCircle(CircleFact circleFact, Transform parent = null)
    
    ki7077's avatar
    ki7077 committed
            GameObject circle = Instantiate(Circle, parent);
    
    MaZiFAU's avatar
    MaZiFAU committed
            circle.transform.localScale = Vector3.Scale(circle.transform.localScale, circleFact.LocalScale);
    
        public void SpawnQuad(QuadFact fact)
        {
            GameObject prism = GameObject.Instantiate(Prism);
            fact.WorldRepresentation = prism.GetComponentInChildren<FactObject3D>();
            fact.WorldRepresentation.Fact = fact;
    
            prism.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
    
            PrismGenerator[] prisms = prism.GetComponentsInChildren<PrismGenerator>();
            foreach (var gen in prisms)
                gen.Vertices = fact.Points.Select(p => p.Position).ToArray();
        }
    
    
        public void SpawnTris(TriangleFact fact)
        {
            GameObject prism = GameObject.Instantiate(Prism);
            fact.WorldRepresentation = prism.GetComponentInChildren<FactObject3D>();
            fact.WorldRepresentation.Fact = fact;
    
            prism.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
    
            PrismGenerator[] prisms = prism.GetComponentsInChildren<PrismGenerator>();
            foreach (var gen in prisms)
                gen.Vertices = fact.Verticies;
        }
    
    
        public void SpawnCone(ConeVolumeFact fact)
        {
            GameObject prism = GameObject.Instantiate(Cone);
            fact.WorldRepresentation = prism.GetComponentInChildren<FactObject3D>();
            fact.WorldRepresentation.Fact = fact;
    
            prism.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
    
            ConeGenerator[] prisms = prism.GetComponentsInChildren<ConeGenerator>();
            foreach (var gen in prisms)
            {
                gen.topPosition = fact.Point.Position - fact.Circle.Position;
                gen.topRadius = 0f;
                gen.bottomRadius = fact.Circle.radius;
            }
        }
    
        public void SpawnTruncatedCone(TruncatedConeVolumeFact fact)
        {
            GameObject prism = GameObject.Instantiate(Cone);
            fact.WorldRepresentation = prism.GetComponentInChildren<FactObject3D>();
            fact.WorldRepresentation.Fact = fact;
    
            prism.transform.SetPositionAndRotation(fact.Position, fact.Rotation);
    
            ConeGenerator[] prisms = prism.GetComponentsInChildren<ConeGenerator>();
            foreach (var gen in prisms)
            {
                gen.topPosition = fact.CircleTop.Position - fact.CircleBase.Position;
                gen.topRadius = fact.CircleTop.radius;
                gen.bottomRadius = fact.CircleBase.radius;
            }
        }
    
    
        public void AnimateNonExistingFactTrigger(Fact fact)
    
    MaZiFAU's avatar
    MaZiFAU committed
        {
    
    MaZiFAU's avatar
    MaZiFAU committed
            StartCoroutine(_BlossomAndDie(fact));
    
    MaZiFAU's avatar
    MaZiFAU committed
            IEnumerator _BlossomAndDie(Fact fact)
    
                yield return new WaitForSeconds(GlobalBehaviour.HintAnimationDuration);
    
                RemoveFactEvent.Invoke(fact);
    
                fact.freeAutoLabel(StageStatic.stage.factState);
    
    MaZiFAU's avatar
    MaZiFAU committed
            float MaxAnimationDuration = 10f;
    
            StartCoroutine(_AnimateFunctionCalls());
    
            IEnumerator _AnimateFunctionCalls()
            {
                float trigger_time = Time.time;
    
                Queue<FunctionCallFact> FCFs = new(
                    StageStatic.stage.factState.MyFactSpace.Values
                    .Where(f => f is FunctionCallFact)
                    .Select(f => f as FunctionCallFact)
                    .OrderBy(f => f.Domain.t_0)
                );
    
                FCFs.TryDequeue(out FunctionCallFact up_next);
                while (up_next != null)
                {
                    float curren_time = Time.time - trigger_time;
                    while (up_next != null && up_next.Domain.t_0 <= curren_time)
                    {
                        if (up_next.Domain.t_n <= curren_time)
                        {
                            FCFs.TryDequeue(out up_next);
                            continue;
                        }
                        StartCoroutine(__BlossomDragAndDie(up_next));
                        FCFs.TryDequeue(out up_next);
                    }
                    yield return null;
                }
    
    
    MaZiFAU's avatar
    MaZiFAU committed
    #pragma warning disable CS8321 // Die lokale Funktion ist deklariert, wird aber nie verwendet.
    
                IEnumerator __BlossomAndDiePerFrame(FunctionCallFact FCF)
                {
                    float current_time = Time.time - trigger_time;
                    while (current_time <= FCF.Domain.t_n
                        && current_time <= FCF.Domain.t_0 + MaxAnimationDuration)
                    {
                        object[] result = FCF.Call(current_time);
    
                        List<Fact> factlist = new();
                        foreach (object i in result)
    
                            Fact.MakeFact(factlist, i, null, true);
    
    
                        foreach (Fact fact in factlist)
                            SpawnFactRepresentation(fact);
    
                        yield return null;
    
                        foreach (Fact fact in factlist)
                        {
                            RemoveFactEvent.Invoke(fact);
    
                            fact.freeAutoLabel(StageStatic.stage.factState);
    
    MaZiFAU's avatar
    MaZiFAU committed
    #pragma warning restore CS8321 // Die lokale Funktion ist deklariert, wird aber nie verwendet.
    
    
                IEnumerator __BlossomDragAndDie(FunctionCallFact FCF)
                {
                    List<Fact> factlist = new();
    
                    object[] result = FCF.Call(FCF.Domain.t_0);
                    foreach (object i in result)
    
                        Fact.MakeFact(factlist, i, null, true);
    
    
                    foreach (Fact fact in factlist)
                        SpawnFactRepresentation(fact);
    
                    float current_time = Time.time - trigger_time;
                    while (current_time <= FCF.Domain.t_n
                        && current_time <= FCF.Domain.t_0 + MaxAnimationDuration)
                    {
                        List<Fact> factlist_media = new();
    
                        object[] result_media = FCF.Call(current_time);
                        foreach (object i in result_media)
    
                            Fact.MakeFact(factlist_media, i, null, true);
    
    
                        for (int i = 0; i < math.min(factlist.Count, factlist_media.Count); i++)
                        {
                            //factlist[i].WorldRepresentation.Fact = factlist_media[i]; //TODO? viable? => FactWrapper.FactUpdated()
                            factlist[i].WorldRepresentation.transform.SetPositionAndRotation(
                                factlist_media[i].Position,
                                factlist_media[i].Rotation
                            );
    
                            factlist_media[i].freeAutoLabel(StageStatic.stage.factState);
    
                        }
    
                        yield return null;
                        current_time = Time.time - trigger_time;
                    }
    
                    foreach (Fact fact in factlist)
                    {
                        RemoveFactEvent.Invoke(fact);
    
                        fact.freeAutoLabel(StageStatic.stage.factState);