From 8284530d40ba886a398e9cf6d95b33a162b1636d Mon Sep 17 00:00:00 2001
From: unknown <john.schihada@hotmail.com>
Date: Fri, 20 Dec 2019 16:10:14 +0100
Subject: [PATCH] Added Angle-Preview

---
 Assets/FactManager.cs                         | 99 ++++++++++++++-----
 .../InteractionEngine/CommunicationEvents.cs  |  6 +-
 Assets/InteractionEngine/ShinyThings.cs       | 88 ++++++++++++++---
 Assets/InteractionEngine/WorldCursor.cs       | 12 ++-
 Assets/TreeWorld.unity                        |  5 +-
 5 files changed, 159 insertions(+), 51 deletions(-)

diff --git a/Assets/FactManager.cs b/Assets/FactManager.cs
index d378c4c0..b0c4cd6a 100644
--- a/Assets/FactManager.cs
+++ b/Assets/FactManager.cs
@@ -1,4 +1,5 @@
-using System.Collections;
+using System;
+using System.Collections;
 using System.Collections.Generic;
 using TMPro;
 using UnityEngine;
@@ -8,9 +9,13 @@ public class FactManager : MonoBehaviour
     public GameObject SmartMenu;
     private Stack<int> NextEmptyStack = new Stack<int>();
 
-    //Variable for LineMode distinction
-    public bool lineModeFirstPointSelected = false;
-    public Fact firstPointSelected = null;
+    //Variables for LineMode distinction
+    public bool lineModeIsFirstPointSelected = false;
+    public Fact lineModeFirstPointSelected = null;
+
+    //Variables for AngleMode distinction
+    public bool angleModeIsFirstLineSelected = false;
+    public Fact angleModeFirstLineSelected = null;
 
     // Start is called before the first frame update
     void Start()
@@ -41,7 +46,7 @@ PointFact AddPointFact(RaycastHit hit, int id)
             Normal = hit.normal
         });
 
-        return Facts[id] as PointFact;
+        return Facts.Find(x => x.Id == id) as PointFact;
     }
 
     LineFact AddLineFact(int pid1, int pid2, int id)
@@ -53,7 +58,7 @@ LineFact AddLineFact(int pid1, int pid2, int id)
             Pid2 = pid2
         });
 
-        return Facts[id] as LineFact;
+        return Facts.Find(x => x.Id == id) as LineFact;
     }
 
     AngleFact AddAngleFact(int pid1, int pid2, int pid3, int id)
@@ -66,7 +71,7 @@ AngleFact AddAngleFact(int pid1, int pid2, int pid3, int id)
             Pid3 = pid3
         });
 
-        return Facts[id] as AngleFact;
+        return Facts.Find(x => x.Id == id) as AngleFact;
     }
 
     public void DeleteFact(Fact fact)
@@ -103,6 +108,7 @@ public void OnToolModeChanged(ToolMode ActiveToolMode)
     {
         //We need to do this somehwere...
         CommunicationEvents.ActiveToolMode = ActiveToolMode;
+
         switch (ActiveToolMode)
         {
             case ToolMode.MarkPointMode:
@@ -181,32 +187,34 @@ public void OnHit(RaycastHit hit)
                 {
                     Fact tempFact = Facts[hit.transform.GetComponent<FactObject>().Id];
 
-                    if (this.lineModeFirstPointSelected)
+                    if (this.lineModeIsFirstPointSelected)
                     {
-                        //Event for end of line-rendering in "ShinyThings"
-                        CommunicationEvents.StopLineRendererEvent.Invoke(null);
+                        //Event for end of line-drawing in "ShinyThings"
+                        CommunicationEvents.StopLineDrawingEvent.Invoke(null);
                         //Create LineFact
-                        CommunicationEvents.AddFactEvent.Invoke(this.AddLineFact(this.firstPointSelected.Id, tempFact.Id, this.GetFirstEmptyID()));
-                        this.lineModeFirstPointSelected = false;
-                        this.firstPointSelected = null;
+                        CommunicationEvents.AddFactEvent.Invoke(this.AddLineFact(this.lineModeFirstPointSelected.Id, tempFact.Id, this.GetFirstEmptyID()));
+                        this.lineModeIsFirstPointSelected = false;
+                        this.lineModeFirstPointSelected = null;
                     }
-                    else {
-                        //Activate LineRenderer for preview
-                        this.lineModeFirstPointSelected = true;
-                        this.firstPointSelected = tempFact;
-                        //Event for start line-rendering in "ShinyThings"
-                        CommunicationEvents.StartLineRendererEvent.Invoke(this.firstPointSelected);
+                    else
+                    {
+                        //Activate LineDrawing for preview
+                        this.lineModeIsFirstPointSelected = true;
+                        this.lineModeFirstPointSelected = tempFact;
+                        //Event for start line-drawing in "ShinyThings"
+                        CommunicationEvents.StartLineDrawingEvent.Invoke(this.lineModeFirstPointSelected);
                     }
                 }
                 //If no Point was hit
-                else {
-                    if (this.lineModeFirstPointSelected)
+                else
+                {
+                    if (this.lineModeIsFirstPointSelected)
                     {
-                        //Deactivate LineRendering and first point selection
-                        this.lineModeFirstPointSelected = false;
-                        this.firstPointSelected = null;
-                        //Event for end of line-rendering in "ShinyThings"
-                        CommunicationEvents.StopLineRendererEvent.Invoke(null);
+                        //Deactivate LineDrawing and first point selection
+                        this.lineModeIsFirstPointSelected = false;
+                        this.lineModeFirstPointSelected = null;
+                        //Event for end of line-drawing in "ShinyThings"
+                        CommunicationEvents.StopLineDrawingEvent.Invoke(null);
                     }
 
                     //TODO: Hint that only a line can be drawn between already existing points
@@ -214,12 +222,49 @@ public void OnHit(RaycastHit hit)
                 break;
             //If Left-Mouse-Button was pressed in CreateAngleMode
             case ToolMode.CreateAngleMode:
+                //Check if an existing Line was hit
+                if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Line"))
+                {
+                    Fact tempFact = Facts[hit.transform.GetComponent<FactObject>().Id];
+
+                    if (this.angleModeIsFirstLineSelected)
+                    {
+                        //Event for end of line-rendering in "ShinyThings"
+                        CommunicationEvents.StopCurveDrawingEvent.Invoke(null);
+                        //Create AngleFact
+                        //TODO: CommunicationEvents.AddFactEvent.Invoke(this.AddAngleFact());
+                        this.angleModeIsFirstLineSelected = false;
+                        this.angleModeFirstLineSelected = null;
+                    }
+                    else
+                    {
+                        //Activate CurveDrawing for preview
+                        this.angleModeIsFirstLineSelected = true;
+                        this.angleModeFirstLineSelected = tempFact;
+                        //Event for start line-rendering in "ShinyThings"
+                        CommunicationEvents.StartCurveDrawingEvent.Invoke(this.angleModeFirstLineSelected);
+                    }
+                }
+                else
+                {
+                    if (this.angleModeIsFirstLineSelected)
+                    {
+                        //Deactivate CurveDrawing and first line selection
+                        this.angleModeIsFirstLineSelected = false;
+                        this.angleModeFirstLineSelected = null;
+                        //Event for end of line-drawing in "ShinyThings"
+                        CommunicationEvents.StopCurveDrawingEvent.Invoke(null);
+                    }
+
+                    //TODO: Hint that only a curve can be drawn between already existing lines
+                }
                 break;
             //If Left-Mouse-Button was pressed in DeleteMode
             case ToolMode.DeleteMode:
                 //Search for the Fact that was hit
                 //If the hit GameObject was a Point/Line/Angle
-                if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Point") || hit.transform.gameObject.layer == LayerMask.NameToLayer("Line") || hit.transform.gameObject.layer == LayerMask.NameToLayer("Angle")){
+                if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Point") || hit.transform.gameObject.layer == LayerMask.NameToLayer("Line") || hit.transform.gameObject.layer == LayerMask.NameToLayer("Angle"))
+                {
                     //Search for the suitable fact from the List
                     this.DeleteFact(Facts.Find(x => x.Id == hit.transform.GetComponent<FactObject>().Id));
                 }
diff --git a/Assets/InteractionEngine/CommunicationEvents.cs b/Assets/InteractionEngine/CommunicationEvents.cs
index 1439c662..93724547 100644
--- a/Assets/InteractionEngine/CommunicationEvents.cs
+++ b/Assets/InteractionEngine/CommunicationEvents.cs
@@ -59,8 +59,10 @@ public class ShinyEvent : UnityEvent<Fact> {
     //public static MouseOverFactEvent HighlightEvent = new MouseOverFactEvent();
     //public static MouseOverFactEvent EndHighlightEvent = new MouseOverFactEvent();
 
-    public static ShinyEvent StartLineRendererEvent = new ShinyEvent();
-    public static ShinyEvent StopLineRendererEvent = new ShinyEvent();
+    public static ShinyEvent StartLineDrawingEvent = new ShinyEvent();
+    public static ShinyEvent StopLineDrawingEvent = new ShinyEvent();
+    public static ShinyEvent StartCurveDrawingEvent = new ShinyEvent();
+    public static ShinyEvent StopCurveDrawingEvent = new ShinyEvent();
 
 
 
diff --git a/Assets/InteractionEngine/ShinyThings.cs b/Assets/InteractionEngine/ShinyThings.cs
index 08610be0..abf1cef7 100644
--- a/Assets/InteractionEngine/ShinyThings.cs
+++ b/Assets/InteractionEngine/ShinyThings.cs
@@ -1,10 +1,10 @@
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
+using static CommunicationEvents;
 
 public class ShinyThings : MonoBehaviour
 {
-
     public WorldCursor Cursor;
     //Attributes for Highlighting of Facts when Mouse-Over
     private string selectableTag = "Selectable";
@@ -13,17 +13,25 @@ public class ShinyThings : MonoBehaviour
     public Material highlightMaterial;
 
 
-    //Attributes for simulating the drawing of a line
+    //Attributes for simulating the drawing of a line/curve
     public LineRenderer lineRenderer;
     private List<Vector3> linePositions = new List<Vector3>();
-    private bool lineRendererActivated;
+
+    private bool lineDrawingActivated;
+    private bool curveDrawingActivated;
+    private int curveDrawingVertexCount = 12;
+    private LineFact curveDrawingStartLine;
+    private Vector3 curveEndPoint;
+    private Vector3 angleMiddlePoint;
 
     // Start is called before the first frame update
     public void Start()
     {
-        if(Cursor == null)Cursor = GetComponent<WorldCursor>();
-       CommunicationEvents.StartLineRendererEvent.AddListener(ActivateLineDrawing);
-       CommunicationEvents.StopLineRendererEvent.AddListener(DeactivateLineDrawing);
+        if (Cursor == null) Cursor = GetComponent<WorldCursor>();
+        CommunicationEvents.StartLineDrawingEvent.AddListener(ActivateLineDrawing);
+        CommunicationEvents.StopLineDrawingEvent.AddListener(DeactivateLineDrawing);
+        CommunicationEvents.StartCurveDrawingEvent.AddListener(ActivateCurveDrawing);
+        CommunicationEvents.StopCurveDrawingEvent.AddListener(DeactivateCurveDrawing);
     }
 
     // Update is called once per frame
@@ -58,8 +66,10 @@ public void Update()
             //SELECTION-HIGHLIGHTING-PART-END
 
             //LineRendering-Part
-            if (this.lineRendererActivated)
+            if (this.lineDrawingActivated)
                 UpdateLineDrawing(Hit.point);
+            else if (this.curveDrawingActivated)
+                UpdateCurveDrawing(Hit.point);
         }
 
 
@@ -92,9 +102,12 @@ public void OnMouseOverFactEnd(Transform selection)
         }
     }
 
-    public void ActivateLineDrawing(Fact startFact) {
-        //Set LineRenderer activated
-        this.lineRendererActivated = true;
+    public void ActivateLineDrawing(Fact startFact)
+    {
+        lineRenderer.startWidth = 0.095f;
+        lineRenderer.endWidth = 0.095f;
+        //Set LineDrawing activated
+        this.lineDrawingActivated = true;
         //Add the position of the Fact for the start of the Line
         linePositions.Add(startFact.Representation.transform.position);
         //The second point is the same point at the moment
@@ -112,7 +125,7 @@ public void UpdateLineDrawing(Vector3 currentPosition)
         this.lineRenderer.SetPosition(1, this.linePositions[1]);
     }
 
-    //Deactivate LineRenderer so that no Line gets drawn when Cursor changes
+    //Deactivate LineDrawing so that no Line gets drawn when Cursor changes
     public void DeactivateLineDrawing(Fact startFact)
     {
         //Reset the first points
@@ -120,18 +133,63 @@ public void DeactivateLineDrawing(Fact startFact)
         this.lineRenderer.SetPosition(1, Vector3.zero);
         if (linePositions.Count > 0)
             this.linePositions.Clear();
-        this.lineRendererActivated = false;
+        this.lineDrawingActivated = false;
     }
 
-    public void ActivateCurveDrawing(Fact startFact) {
+    //Expect a LineFact here, so that it's possible to change between two possible StartPoints
+    public void ActivateCurveDrawing(Fact startFact)
+    {
+        lineRenderer.startWidth = 0.05f;
+        lineRenderer.endWidth = 0.05f;
+
+        //Set CurveDrawing activated
+        this.curveDrawingActivated = true;
+
+        curveDrawingStartLine = (LineFact)startFact;
+
+        curveEndPoint = Cursor.transform.position;
+
+        //Determine which point of the line is closer to the cursor and initialize angleMiddlePoint
+        //angleMiddlePoint is needed for the Angle  Preview
+        float Distance1 = (Facts.Find(x => x.Id == curveDrawingStartLine.Pid1).Representation.transform.position - curveEndPoint).magnitude;
+        float Distance2 = (Facts.Find(x => x.Id == curveDrawingStartLine.Pid2).Representation.transform.position - curveEndPoint).magnitude;
+
+        if (Distance1 >= Distance2)
+            angleMiddlePoint = Facts.Find(x => x.Id == curveDrawingStartLine.Pid2).Representation.transform.position;
+        else
+            angleMiddlePoint = Facts.Find(x => x.Id == curveDrawingStartLine.Pid1).Representation.transform.position;
 
     }
 
-    public void UpdateCurveDrawing(Vector3 currentPosition) {
+    public void UpdateCurveDrawing(Vector3 currentPosition)
+    {
+        //Determine the Center of Start-Point and End-Point 
+        Vector3 tempCenterPoint = Vector3.Lerp(currentPosition, curveEndPoint, 0.5f);
+        Vector3 curveMiddlePoint = angleMiddlePoint + 2 * (tempCenterPoint - angleMiddlePoint);
+        
+        linePositions = new List<Vector3>();
 
+        for (float ratio = 0; ratio <= 1; ratio += 1.0f / this.curveDrawingVertexCount)
+        {
+            var tangentLineVertex1 = Vector3.Lerp(currentPosition, curveMiddlePoint, ratio);
+            var tangentLineVertex2 = Vector3.Lerp(curveMiddlePoint, curveEndPoint, ratio);
+            var bezierPoint = Vector3.Lerp(tangentLineVertex1, tangentLineVertex2, ratio);
+            linePositions.Add(bezierPoint);
+        }
+
+        lineRenderer.positionCount = linePositions.Count;
+        lineRenderer.SetPositions(linePositions.ToArray());
     }
 
-    public void DeactivateCurveDrawing(Fact startFact) {
+    public void DeactivateCurveDrawing(Fact startFact)
+    {
 
+        for (int i = 0; i < linePositions.Count; i++)
+        {
+            this.lineRenderer.SetPosition(i, Vector3.zero);
+        }
+        if (linePositions.Count > 0)
+            this.linePositions.Clear();
+        this.curveDrawingActivated = false;
     }
 }
diff --git a/Assets/InteractionEngine/WorldCursor.cs b/Assets/InteractionEngine/WorldCursor.cs
index 42b7c51d..9cff6115 100644
--- a/Assets/InteractionEngine/WorldCursor.cs
+++ b/Assets/InteractionEngine/WorldCursor.cs
@@ -69,16 +69,18 @@ void CheckMouseButtons(Ray ray)
     //Checks if the ToolMode was switched by User, and handle it
     void CheckToolModeSelection() {
         if (Input.GetButtonDown("ToolMode")) {
+            ToolMode tempActiveToolMode = CommunicationEvents.ActiveToolMode;
             //Change the ActiveToolMode dependent on which Mode was selected
-            if ((int)ActiveToolMode == Enum.GetNames(typeof(ToolMode)).Length - 1)
+            if ((int)tempActiveToolMode == Enum.GetNames(typeof(ToolMode)).Length - 1)
             {
-                ActiveToolMode = 0;
+                tempActiveToolMode = 0;
             }
-            else {
-                ActiveToolMode++;
+            else
+            {
+                tempActiveToolMode++;
             }
             //Invoke the Handler for the Facts
-            CommunicationEvents.ToolModeChangedEvent.Invoke(ActiveToolMode);
+            CommunicationEvents.ToolModeChangedEvent.Invoke(tempActiveToolMode);
         }
     }
 
diff --git a/Assets/TreeWorld.unity b/Assets/TreeWorld.unity
index 01a20177..08fa6397 100644
--- a/Assets/TreeWorld.unity
+++ b/Assets/TreeWorld.unity
@@ -1181,7 +1181,7 @@ LineRenderer:
       m_Curve:
       - serializedVersion: 3
         time: 0.0102005005
-        value: 0.16666985
+        value: 0.1541729
         inSlope: 0
         outSlope: 0
         tangentMode: 0
@@ -1258,7 +1258,8 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   SmartMenu: {fileID: 5601740127768851631, guid: e693bf633c633d243b0254d117ec3893,
     type: 3}
-  lineModeFirstPointSelected: 0
+  lineModeIsFirstPointSelected: 0
+  angleModeIsFirstLineSelected: 0
 --- !u!1 &1675643434
 GameObject:
   m_ObjectHideFlags: 0
-- 
GitLab