// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. using HoloToolkit.Unity; using UnityEngine; namespace HoloToolkit.Unity.UX { public abstract class LineRendererBase : MonoBehaviour { [SerializeField] [Tooltip("The source Line this component will render")] protected LineBase source; [Header("Visual Settings")] [Tooltip("Color gradient applied to line's normalized length")] public Gradient LineColor; public AnimationCurve LineWidth = AnimationCurve.Linear(0f, 0.05f, 1f, 0.05f); [Range(0f, 10f)] public float WidthMultiplier = 0.25f; [Header("Offsets")] [Range(0f, 10f)] [Tooltip("Normalized offset for color gradient")] public float ColorOffset = 0f; [Range(0f, 10f)] [Tooltip("Normalized offset for width curve")] public float WidthOffset = 0f; [Range(0f, 10f)] [Tooltip("Normalized offset for rotation offset")] public float RotationOffset = 0f; [Header("Point Placement")] [Tooltip("Method for gathering points along line. Interpolated uses normalized length. FromSource uses line's base points. (FromSource may not look right for all Line types.)")] public StepModeEnum StepMode = StepModeEnum.Interpolated; [Range(0, 2048)] [Tooltip("Number of steps to interpolate along line in Interpolated step mode")] [ShowIfEnumValue("StepMode", StepModeEnum.Interpolated)] public int NumLineSteps = 10; [FeatureInProgress] public InterpolationModeEnum InterpolationMode = InterpolationModeEnum.FromLength; [FeatureInProgress] [Range(0.001f, 1f)] public float StepLength = 0.05f; [FeatureInProgress] [Range(1, 2048)] public int MaxLineSteps = 2048; [FeatureInProgress] public AnimationCurve StepLengthCurve = AnimationCurve.Linear(0f, 1f, 1f, 0.5f); public virtual LineBase Source { get { if (source == null) { source = GetComponent<LineBase>(); } return source; } set { source = value; if (source == null) { enabled = false; } } } protected virtual Color GetColor(float normalizedLength) { if (LineColor == null) { LineColor = new Gradient(); } return LineColor.Evaluate(Mathf.Repeat(normalizedLength + ColorOffset, 1f)); } protected virtual float GetWidth(float normalizedLength) { if (LineWidth == null) { LineWidth = AnimationCurve.Linear(0f, 1f, 1f, 1f); } return LineWidth.Evaluate(Mathf.Repeat(normalizedLength + WidthOffset, 1f)) * WidthMultiplier; } private float[] normalizedLengths; #if UNITY_EDITOR protected virtual void OnDrawGizmos() { if (Application.isPlaying) return; if (source == null) source = gameObject.GetComponent<LineBase>(); if (source == null || !source.enabled) return; GizmosDrawLineRenderer(source, this); } public static void GizmosDrawLineRenderer(LineBase source, LineRendererBase renderer) { switch (renderer.StepMode) { case StepModeEnum.FromSource: GizmosDrawLineFromSource(source, renderer); break; case StepModeEnum.Interpolated: GizmosDrawLineInterpolated(source, renderer); break; } } public static void GizmosDrawLineFromSource(LineBase source, LineRendererBase renderer) { Vector3 firstPos = source.GetPoint(0); Vector3 lastPos = firstPos; Color gColor = renderer.GetColor(0); gColor.a = 0.5f; Gizmos.color = gColor; Gizmos.DrawSphere(firstPos, renderer.GetWidth(0) / 2); for (int i = 1; i < source.NumPoints; i++) { float normalizedLength = (1f / (source.NumPoints)) * i; Vector3 currentPos = source.GetPoint(i); gColor = renderer.GetColor(normalizedLength); gColor.a = gColor.a * 0.5f; Gizmos.color = gColor; Gizmos.DrawLine(lastPos, currentPos); Gizmos.DrawSphere(currentPos, renderer.GetWidth(normalizedLength) / 2); lastPos = currentPos; } if (source.Loops) { Gizmos.DrawLine(lastPos, firstPos); } } public static void GizmosDrawLineInterpolated(LineBase source, LineRendererBase renderer) { Vector3 firstPos = source.GetPoint(0f); Vector3 lastPos = firstPos; Color gColor = renderer.GetColor(0); gColor.a = 0.5f; Gizmos.color = gColor; Gizmos.DrawSphere(firstPos, renderer.GetWidth(0) / 2); for (int i = 1; i <= renderer.NumLineSteps; i++) { float normalizedLength = (1f / (renderer.NumLineSteps)) * i; Vector3 currentPos = source.GetPoint(normalizedLength); gColor = renderer.GetColor(normalizedLength); gColor.a = gColor.a * 0.5f; Gizmos.color = gColor; Gizmos.DrawLine(lastPos, currentPos); Gizmos.DrawSphere(currentPos, renderer.GetWidth(normalizedLength) / 2); lastPos = currentPos; } if (source.Loops) { Gizmos.DrawLine(lastPos, firstPos); } } #endif } }