Skip to content
Snippets Groups Projects
Select Git revision
  • cda734c94023b880e7779a4b49023be6afc1517c
  • master default
  • JS-based-scroll-rendering
  • Paul_Marius_Level
  • Paul_Marius_2
  • Paul_Marius
  • Andi_Mark
  • be-UnityWebView
  • gitignoreFrameitServer
  • ZimmerBSc
  • Bugfix_StageLoading
  • stages
  • MAZIFAU_Experimental
  • tsc/coneworld
  • tsc/fact-interaction
  • marcel
  • MaZiFAU_TopSort
  • mergeHelper
  • zwischenSpeichern
  • tempAndrToMaster
  • SebBranch
  • 3.0
  • v2.1
  • v2.0
  • v1.0
25 results

AbstractLineFact.cs

Blame
  • user avatar
    MaZiFAU authored
    cda734c9
    History
    AbstractLineFact.cs 10.67 KiB
    using Newtonsoft.Json;
    using System.Collections.Generic;
    using TMPro;
    using UnityEngine;
    using static SOMDocManager;
    
    /// <summary>
    /// Base-class for 1D-Facts
    /// </summary>
    public abstract class AbstractLineFact : FactWrappedCRTP<AbstractLineFact>
    {
        /// @{ <summary>
        /// One <see cref="Fact.Id">Id</see> of two <see cref="PointFact"/> defining <see cref="Dir"/>.
        /// </summary>
        public string Pid1, Pid2;
        /// @}
    
        [JsonIgnore]
        public PointFact Point1 { get => (PointFact)FactOrganizer.AllFacts[Pid1]; }
        [JsonIgnore]
        public PointFact Point2 { get => (PointFact)FactOrganizer.AllFacts[Pid2]; }
    
        /// <summary> Distance between <see cref="AbstractLineFact.Pid1"/> and <see cref="AbstractLineFact.Pid2"/></summary>
        [JsonIgnore]
        public float Distance;
    
        /// <summary>
        /// Normalized Direction from <see cref="Pid1"/> to <see cref="Pid2"/>.
        /// </summary>
        public Vector3 Dir;
    
        /// <summary>
        /// \copydoc Fact.Fact()
        /// </summary>
        protected AbstractLineFact() : base()
        {
            Pid1 = null;
            Pid2 = null;
            Dir = Vector3.zero;
        }
    
        /// <summary>
        /// Standard Constructor
        /// </summary>
        /// <param name="pid1">sets <see cref="AbstractLineFact.Pid1"/></param>
        /// <param name="pid2">sets <see cref="AbstractLineFact.Pid2"/></param>
        /// <param name="organizer">sets <see cref="Fact._Facts"/></param>
        protected AbstractLineFact(string pid1, string pid2, FactOrganizer organizer) : base(organizer)
        {
            set_public_members(pid1, pid2);
        }
    
        /// <summary>
        /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_.
        /// </summary>
        /// <param name="pid1">sets <see cref="Pid1"/></param>
        /// <param name="pid2">sets <see cref="Pid2"/></param>
        /// <param name="backendURI">MMT URI</param>
        /// <param name="organizer">sets <see cref="Fact._Facts"/></param>
        protected AbstractLineFact(string pid1, string pid2, string backendURI, FactOrganizer organizer) : base(organizer)
        {
            this._URI = backendURI;
            set_public_members(pid1, pid2);
        }
    
        /// <summary>
        /// Initiates <see cref="Pid1"/>, <see cref="Pid2"/>, <see cref="Dir"/>
        /// </summary>
        /// <param name="pid1">sets <see cref="Pid1"/></param>
        /// <param name="pid2">sets <see cref="Pid2"/></param>
        private void set_public_members(string pid1, string pid2)
        {
            this.Pid1 = pid1;
            this.Pid2 = pid2;
            Vector3 diff = (Point1.Point - Point2.Point);
            this.Dir = diff.normalized;
            this.Distance = diff.magnitude;
        }
    
        protected override void RecalculateTransform()
        {
            Position = Vector3.Lerp(Point1.Point, Point2.Point, 0.5f);
            Rotation = Quaternion.LookRotation(Dir, Vector3.up);
            LocalScale = new Vector3(1, 1, Distance);
        }
    
        /// \copydoc Fact.hasDependentFacts
        public override bool HasDependentFacts => true;
    
        /// \copydoc Fact.getDependentFactIds
        protected override string[] GetGetDependentFactIds()
        {
            return new string[] { Pid1, Pid2 };
        }
    }
    
    /// <summary>
    /// Implements CRTP for <see cref="AbstractLineFact"/>; Escalates constructors;
    /// </summary>
    /// <typeparam name="T">class, which inherits from AbstractLineFactWrappedCRTP</typeparam>
    public abstract class AbstractLineFactWrappedCRTP<T> : AbstractLineFact where T : AbstractLineFactWrappedCRTP<T>
    {
        /// <summary>\copydoc Fact.Fact</summary>
        protected AbstractLineFactWrappedCRTP() : base() { }
    
        /// <summary>\copydoc AbstractLineFact.AbstractLineFact(string, string, FactOrganizer)</summary>
        protected AbstractLineFactWrappedCRTP(string pid1, string pid2, FactOrganizer organizer) : base(pid1, pid2, organizer) { }
    
        /// <summary>\copydoc AbstractLineFact.AbstractLineFact(string, string, string, FactOrganizer)</summary>
        protected AbstractLineFactWrappedCRTP(string pid1, string pid2, string backendURI, FactOrganizer organizer) : base(pid1, pid2, backendURI, organizer) { }
    
        /// \copydoc Fact.Equivalent(Fact, Fact)
        protected override bool EquivalentWrapped(AbstractLineFact f1, AbstractLineFact f2)
            => EquivalentWrapped((T)f1, (T)f2);
    
        /// <summary>CRTP step of <see cref="EquivalentWrapped(AbstractLineFact, AbstractLineFact)"/></summary>
        protected abstract bool EquivalentWrapped(T f1, T f2);
    }
    
    /// <summary>
    /// Line within 3D Space of finite length
    /// </summary>
    public class LineFact : AbstractLineFactWrappedCRTP<LineFact>
    {
        /// \copydoc Fact.s_type
        [JsonProperty]
        protected static new string s_type = "LineFact";
    
        /// <summary> \copydoc Fact.Fact </summary>
        public LineFact() : base() { }
    
        /// <summary> \copydoc AbstractLineFact.AbstractLineFact(string, string, string, FactOrganizer) </summary>
        public LineFact(string pid1, string pid2, string backendURI, FactOrganizer organizer) : base(pid1, pid2, backendURI, organizer) 
            => _ = this.Label;
    
        /// <summary> \copydoc AbstractLineFact.AbstractLineFact(string, string, FactOrganizer) </summary>
        public LineFact(string pid1, string pid2, FactOrganizer organizer) : base(pid1, pid2, organizer)
        {
            AddFactResponse.sendAdd(MakeMMTDeclaration(), out this._URI);
        }
    
        protected override MMTDeclaration MakeMMTDeclaration()
        {
            SOMDoc lhs =
                new OMA(
                    new OMS(MMT_OMS_URI.Metric),
                    new List<SOMDoc> {
                        new OMS(Pid1),
                        new OMS(Pid2)
                    }
                );
    
            SOMDoc valueTp = new OMS(MMT_OMS_URI.RealLit);
            SOMDoc value = new OMF(Distance);
    
            return new MMTValueDeclaration(this.Label, lhs, valueTp, value);
        }
    
        /// \copydoc Fact.parseFact(Scroll.ScrollFact)
        public new static LineFact parseFact(Scroll.ScrollFact fact)
        {
            string uri = fact.@ref.uri;
            string pointAUri = ((OMS)((OMA)((Scroll.ScrollValueFact)fact).lhs).arguments[0]).uri;
            string pointBUri = ((OMS)((OMA)((Scroll.ScrollValueFact)fact).lhs).arguments[1]).uri;
    
            if (StageStatic.stage.factState.ContainsKey(pointAUri)
             && StageStatic.stage.factState.ContainsKey(pointBUri))
                return new LineFact(pointAUri, pointBUri, uri, StageStatic.stage.factState);
    
            //If dependent facts do not exist return null
            else return null;
        }
    
        /// \copydoc Fact.generateLabel
        protected override string generateLabel()
            => "[" + Point1.Label + Point2.Label + "]";
    
        /// \copydoc Fact.instantiateDisplay(GameObject, Transform)
        public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
        {
            var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
            obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Point1.Label;
            obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Point2.Label;
            obj.GetComponent<FactWrapper>().Fact = this;
            return obj;
        }
    
        /// \copydoc Fact.Equivalent(Fact, Fact)
        protected override bool EquivalentWrapped(LineFact f1, LineFact f2)
            => DependentFactsEquivalent(f1, f2);
    
        protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
            => new LineFact(old_to_new[this.Pid1], old_to_new[this.Pid2], organizer);
    }
    
    /// <summary>
    /// Ray within 3D Space of infinite length
    /// </summary>
    public class RayFact : AbstractLineFactWrappedCRTP<RayFact>
    {
        /// \copydoc Fact.s_type
        [JsonProperty]
        protected static new string s_type = "RayFact";
    
        /// <summary> \copydoc Fact.Fact </summary>
        public RayFact() : base() { }
    
        /// <summary> \copydoc AbstractLineFact.AbstractLineFact(string, string, string, FactOrganizer) </summary>
        public RayFact(string pid1, string pid2, string backendURI, FactOrganizer organizer) : base(pid1, pid2, backendURI, organizer) 
            => _ = this.Label;
    
        /// <summary> \copydoc AbstractLineFact.AbstractLineFact(string, string, FactOrganizer) </summary>
        public RayFact(string pid1, string pid2, FactOrganizer organizer) : base(pid1, pid2, organizer)
        {
            AddFactResponse.sendAdd(MakeMMTDeclaration(), out this._URI);
        }
    
        protected override MMTDeclaration MakeMMTDeclaration()
        {
            SOMDoc tp = new OMS(MMT_OMS_URI.LineType);
            SOMDoc df = new OMA(
                new OMS(MMT_OMS_URI.LineOf),
                new List<SOMDoc> {
                    new OMS(Pid1),
                    new OMS(Pid2)
                });
    
            ParsingDictionary.parseTermsToId[df.ToString()] = this._URI;
            return new MMTSymbolDeclaration(this.Label, tp, df);
        }
    
        protected override void RecalculateTransform()
        {
            base.RecalculateTransform();
            LocalScale = new Vector3(1, 1, 2048);
        }
    
        /// \copydoc Fact.parseFact(Scroll.ScrollFact)
        public new static RayFact parseFact(Scroll.ScrollFact fact)
        {
            string uri = fact.@ref.uri;
    
            if ((OMA)((Scroll.ScrollSymbolFact)fact).df == null)
                return null;
    
            string pointAUri = ((OMS)((OMA)((Scroll.ScrollSymbolFact)fact).df).arguments[0]).uri;
            string pointBUri = ((OMS)((OMA)((Scroll.ScrollSymbolFact)fact).df).arguments[1]).uri;
    
            if (StageStatic.stage.factState.ContainsKey(pointAUri)
                 && StageStatic.stage.factState.ContainsKey(pointBUri))
                return new RayFact(pointAUri, pointBUri, uri, StageStatic.stage.factState);
    
            //If dependent facts do not exist return null
            else return null;
        }
    
        /// \copydoc Fact.generateLabel
        protected override string generateLabel()
        {
            // TODO this string is too large to properly depict on scrolls. 
            // return "]" + _Facts[Pid1].Label + _Facts[Pid2].Label + "[";
            return Point1.Label + Point2.Label;
        }
    
        /// \copydoc Fact.instantiateDisplay(GameObject, Transform)
        public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
        {
            var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
            obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = this.Label;
            obj.GetComponent<FactWrapper>().Fact = this;
            return obj;
        }
    
        /// \copydoc Fact.Equivalent(Fact, Fact)
        protected override bool EquivalentWrapped(RayFact f1, RayFact f2)
        {
            if (!Math3d.IsApproximatelyParallel(f1.Dir, f2.Dir))
                return false;
    
            return Math3d.IsPointApproximatelyOnLine(f1.Point1.Point, f1.Dir, f2.Point1.Point)
                && Math3d.IsPointApproximatelyOnLine(f1.Point1.Point, f1.Dir, f2.Point2.Point);
        }
    
        protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
            => new RayFact(old_to_new[this.Pid1], old_to_new[this.Pid2], organizer);
    }