Newer
Older
HoloAnatomy / Assets / HoloToolkit-Examples / GazeRuler / Scripts / LineManager.cs
SURFACEBOOK2\jackwynne on 25 May 2018 4 KB v1
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using UnityEngine;
using HoloToolkit.Unity;
using System.Collections.Generic;
using HoloToolkit.Unity.InputModule;

namespace HoloToolkit.Examples.GazeRuler
{
    /// <summary>
    /// Manages all lines in the scene
    /// </summary>
    public class LineManager : Singleton<LineManager>, IGeometry
    {
        // save all lines in scene
        private Stack<Line> Lines = new Stack<Line>();

        private Point lastPoint;

        private const float defaultLineScale = 0.005f;

        // place point and lines
        public void AddPoint(GameObject LinePrefab, GameObject PointPrefab, GameObject TextPrefab)
        {

            Vector3 hitPoint = GazeManager.Instance.HitPosition;

            GameObject point = (GameObject)Instantiate(PointPrefab, hitPoint, Quaternion.identity);
            if (lastPoint != null && lastPoint.IsStart)
            {
                Vector3 centerPos = (lastPoint.Position + hitPoint) * 0.5f;
                Vector3 cameraPosition = CameraCache.Main.transform.position;
                Vector3 directionFromCamera = centerPos - cameraPosition;

                float distanceA = Vector3.Distance(lastPoint.Position, cameraPosition);
                float distanceB = Vector3.Distance(hitPoint, cameraPosition);

                Debug.Log("A: " + distanceA + ",B: " + distanceB);
                Vector3 direction;
                if (distanceB > distanceA || (distanceA > distanceB && distanceA - distanceB < 0.1))
                {
                    direction = hitPoint - lastPoint.Position;
                }
                else
                {
                    direction = lastPoint.Position - hitPoint;
                }

                float distance = Vector3.Distance(lastPoint.Position, hitPoint);
                GameObject line = (GameObject)Instantiate(LinePrefab, centerPos, Quaternion.LookRotation(direction));
                line.transform.localScale = new Vector3(distance, defaultLineScale, defaultLineScale);
                line.transform.Rotate(Vector3.down, 90f);

                Vector3 normalV = Vector3.Cross(direction, directionFromCamera);
                Vector3 normalF = Vector3.Cross(direction, normalV) * -1;
                GameObject tip = (GameObject)Instantiate(TextPrefab, centerPos, Quaternion.LookRotation(normalF));

                //unit is meter
                tip.transform.Translate(Vector3.up * 0.05f);
                tip.GetComponent<TextMesh>().text = distance + "m";

                GameObject root = new GameObject();
                lastPoint.Root.transform.parent = root.transform;
                line.transform.parent = root.transform;
                point.transform.parent = root.transform;
                tip.transform.parent = root.transform;

                Lines.Push(new Line
                {
                    Start = lastPoint.Position,
                    End = hitPoint,
                    Root = root,
                    Distance = distance
                });

                lastPoint = new Point
                {
                    Position = hitPoint,
                    Root = point,
                    IsStart = false
                };

            }
            else
            {
                lastPoint = new Point
                {
                    Position = hitPoint,
                    Root = point,
                    IsStart = true
                };
            }
        }


        // delete latest placed lines
        public void Delete()
        {
            if (Lines != null && Lines.Count > 0)
            {
                Line lastLine = Lines.Pop();
                Destroy(lastLine.Root);
            }

        }

        // delete all lines in the scene
        public void Clear()
        {
            if (Lines != null && Lines.Count > 0)
            {
                while (Lines.Count > 0)
                {
                    Line lastLine = Lines.Pop();
                    Destroy(lastLine.Root);
                }
            }
        }

        // reset current unfinished line
        public void Reset()
        {
            if (lastPoint != null && lastPoint.IsStart)
            {
                Destroy(lastPoint.Root);
                lastPoint = null;
            }
        }
    }


    public struct Line
    {
        public Vector3 Start { get; set; }

        public Vector3 End { get; set; }

        public GameObject Root { get; set; }

        public float Distance { get; set; }
    }
}