/****************************************************************************** * Copyright (C) Ultraleap, Inc. 2011-2021. * * * * Use subject to the terms of the Apache License 2.0 available at * * http://www.apache.org/licenses/LICENSE-2.0, or another agreement * * between Ultraleap and you, your company or other organization. * ******************************************************************************/ using UnityEngine; namespace Leap.Unity.Geometry { public struct Bipyramid { public Vector3 a; public Vector3 b; public int polySegments; public float lengthFraction; public float? absoluteRadius; public float? radiusFraction; public Transform transform; private Matrix4x4? overrideMatrix; public Matrix4x4 matrix { get { if (overrideMatrix != null) { return overrideMatrix.Value; } if (transform != null) { return transform.localToWorldMatrix; } return Matrix4x4.identity; } } public float radius { get { if (absoluteRadius != null) { return absoluteRadius.Value; } if (radiusFraction != null) { return (b - a).magnitude * radiusFraction.Value; } else { return (b - a).magnitude * 0.125f; } } } public Bipyramid(Vector3 a, Vector3 b, int polySegments = 6, float lengthFraction = 0.5f, float? radiusFraction = null, float? absoluteRadius = null, Transform transform = null, Matrix4x4? overrideMatrix = null) { this.a = a; this.b = b; this.polySegments = polySegments; this.lengthFraction = lengthFraction; this.radiusFraction = radiusFraction; this.absoluteRadius = absoluteRadius; this.transform = transform; this.overrideMatrix = overrideMatrix; } /// Rig model bone defaults for a bipyramid. Can override any of /// the parameters like a normal bipyramid constructor. public static Bipyramid ModelBone(Vector3 a, Vector3 b, int polySegments = 4, float lengthFraction = 0.38f, float? radiusFraction = 0.0125f, float? absoluteRadius = null, Transform transform = null, Matrix4x4? overrideMatrix = null) { return new Bipyramid(a, b, polySegments: polySegments, lengthFraction: lengthFraction, radiusFraction: radiusFraction, absoluteRadius: absoluteRadius, transform: transform, overrideMatrix: overrideMatrix); } /// Thin directed arrow, good for adding directionality to an edge /// between two points. Can override any of the parameters like a normal /// bipyramid constructor. public static Bipyramid ThinArrow(Vector3 a, Vector3 b, int polySegments = 4, float lengthFraction = 0.3f, float? radiusFraction = null, float? absoluteRadius = 0.005f, Transform transform = null, Matrix4x4? overrideMatrix = null) { return new Bipyramid(a, b, polySegments: polySegments, lengthFraction: lengthFraction, radiusFraction: radiusFraction, absoluteRadius: absoluteRadius, transform: transform, overrideMatrix: overrideMatrix); } /// Arrowhead defaults for a bipyramid. Can override any of /// the parameters like a normal bipyramid constructor. public static Bipyramid Arrowhead(Vector3 a, Vector3 b, int polySegments = 6, float lengthFraction = 0.38f, float? radiusFraction = 0.16f, float? absoluteRadius = null, Transform transform = null, Matrix4x4? overrideMatrix = null) { return new Bipyramid(a, b, polySegments: polySegments, lengthFraction: lengthFraction, radiusFraction: radiusFraction, absoluteRadius: absoluteRadius, transform: transform, overrideMatrix: overrideMatrix); } public void DrawLines(System.Action drawLine) { var matrix = this.matrix; var radius = this.radius; var localLength = (b - a).magnitude; if (localLength == 0f) { localLength = 0.0001f; } var localDirection = (b - a) / localLength; var circle = new Geometry.Circle( center: a + localDirection * localLength * lengthFraction, direction: localDirection, radius: radius, overrideMatrix: matrix ); var startPos = matrix.MultiplyPoint3x4(a); var endPos = matrix.MultiplyPoint3x4(b); foreach (var point in circle.Points(polySegments)) { drawLine(startPos, point); drawLine(point, endPos); } foreach (var edge in circle.Segments(polySegments)) { drawLine(edge.a, edge.b); } } } }