// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. using System; using UnityEngine; namespace HoloToolkit.Unity.UX { public class Bezier : LineBase { [Serializable] private struct PointSet { public PointSet(float spread) { Point1 = Vector3.right * spread * 0.5f; Point2 = Vector3.right * spread * 0.25f; Point3 = Vector3.left * spread * 0.25f; Point4 = Vector3.left * spread * 0.5f; } public Vector3 Point1; public Vector3 Point2; public Vector3 Point3; public Vector3 Point4; } [Header("Bezier Settings")] [SerializeField] private PointSet points = new PointSet(0.5f); public override int NumPoints { get { return 4; } } protected override Vector3 GetPointInternal(int pointIndex) { switch (pointIndex) { case 0: return points.Point1; case 1: return points.Point2; case 2: return points.Point3; case 3: return points.Point4; default: return Vector3.zero; } } protected override void SetPointInternal(int pointIndex, Vector3 point) { switch (pointIndex) { case 0: points.Point1 = point; break; case 1: points.Point2 = point; break; case 2: points.Point3 = point; break; case 3: points.Point4 = point; break; default: break; } } protected override Vector3 GetPointInternal(float normalizedDistance) { return LineUtils.InterpolateBezeirPoints(points.Point1, points.Point2, points.Point3, points.Point4, normalizedDistance); } protected override float GetUnclampedWorldLengthInternal() { // Crude approximation // TODO optimize float distance = 0f; Vector3 last = GetUnclampedPoint(0f); for (int i = 1; i < 10; i++) { Vector3 current = GetUnclampedPoint((float)i / 10); distance += Vector3.Distance(last, current); } return distance; } protected override Vector3 GetUpVectorInternal(float normalizedLength) { // Bezier up vectors just use transform up return transform.up; } #if UNITY_EDITOR [UnityEditor.CustomEditor(typeof(Bezier))] public class CustomEditor : LineBaseEditor { protected override void DrawCustomSceneGUI() { base.DrawCustomSceneGUI(); Bezier line = (Bezier)target; line.SetPoint(0, SphereMoveHandle(line.GetPoint(0))); line.SetPoint(1, SquareMoveHandle(line.GetPoint(1))); line.SetPoint(2, SquareMoveHandle(line.GetPoint(2))); line.SetPoint(3, SphereMoveHandle(line.GetPoint(3))); UnityEditor.Handles.color = handleColorTangent; UnityEditor.Handles.DrawLine(line.GetPoint(0), line.GetPoint(1)); UnityEditor.Handles.DrawLine(line.GetPoint(2), line.GetPoint(3)); } } #endif } }