/// <summary> /// Displays the helix twist curve handles. /// </summary> /// <param name="baseId">Base identifier.</param> /// <param name="helix">Helix.</param> private static void DoHelixTwistHandles(int baseId, Helix helix) { float v; AnimationCurve width = helix.Width; AnimationCurve newTwist = new AnimationCurve(helix.Twist.keys); Keyframe[] newKeys = newTwist.keys; for (int i = 0; i < newKeys.Length; ++i) { // compute the disc center Vector3 discCenter = Vector3.forward * newKeys[i].time * helix.Length; v = newKeys[i].value; // create an arc handle float helixWidth = width.Evaluate(newKeys[i].time); v = ArcHandles.SolidAngle( ObjectX.GenerateHashCode(baseId, s_TwistHandleHash, i, 1), v, discCenter, Quaternion.LookRotation(Vector3.right, Vector3.forward), helixWidth, string.Format("{0:0} Degrees", v) ); Handles.DrawWireDisc(discCenter, Vector3.forward, helixWidth); newKeys[i].value = v; // create time adjustment handles for intermediary keys if (i == 0 || i == newKeys.Length - 1) { continue; } v = newKeys[i].time * helix.Length; int id = ObjectX.GenerateHashCode(baseId, s_TwistHandleHash, i, 2); v = LinearHandles.Cone(id, v, Vector3.zero, Vector3.forward, capScale: s_TimeAdjustHandleSize); v = Mathf.Clamp( v / helix.Length, Mathf.Epsilon * 2f, 1f - Mathf.Epsilon * 2f ); if (Mathf.Abs(v - newKeys[i].time) > s_RequiredMinHandleChange) { newKeys[i].time = v; } // TODO: Fix problems with keys moving over each other } newTwist.keys = newKeys; helix.Twist = newTwist; }
/// <summary> /// Displays helix width handles. /// </summary> /// <param name="baseId">Base identifier.</param> /// <param name="helix">Helix.</param> private static void DoHelixWidthHandles(int baseId, Helix helix) { float v; AnimationCurve twist = helix.Twist; AnimationCurve newWidth = helix.Width; Keyframe[] newKeys = newWidth.keys; for (int i = 0; i < newKeys.Length; ++i) { // compute the disc center Vector3 discCenter = Vector3.forward * newKeys[i].time * helix.Length; // compute the angle of the handle around the length Quaternion angle = Quaternion.AngleAxis(twist.Evaluate(newKeys[i].time), Vector3.forward); // create a cone handle with a slight offset to not overlap the arc handle v = newKeys[i].value + s_WidthHandleOffset; int id = ObjectX.GenerateHashCode(baseId, s_WidthHandleHash, i, 1); v = LinearHandles.Cone(id, v, discCenter, angle * Vector3.right, capScale: s_WidthHandleSize); newKeys[i].value = v - s_WidthHandleOffset; // create time adjustment handles for intermediary keys if (i == 0 || i == newKeys.Length - 1) { continue; } v = newKeys[i].time * helix.Length; id = ObjectX.GenerateHashCode(baseId, s_WidthHandleHash, i, 2); v = LinearHandles.Cone(id, v, Vector3.zero, Vector3.forward, capScale: s_TimeAdjustHandleSize); v = Mathf.Clamp( v / helix.Length, Mathf.Epsilon * 2f, 1f - Mathf.Epsilon * 2f ); if (Mathf.Abs(v - newKeys[i].time) > s_RequiredMinHandleChange) { newKeys[i].time = v; } // TODO: Fix problems with keys moving over each other } newWidth.keys = newKeys; helix.Width = newWidth; }
/// <summary> /// Displays the wedge radius handle. /// </summary> /// <returns>The handle's angle value.</returns> /// <param name="id">Control identifier.</param> /// <param name="radius">Radius.</param> /// <param name="wedgeCenter">Wedge center.</param> /// <param name="direction">Direction.</param> /// <param name="label">Label.</param> private static float WedgeRadiusHandle( int id, float radius, Vector3 wedgeCenter, Vector3 direction, string label ) { return(LinearHandles.Cone(id, radius, wedgeCenter, direction, label, s_RadiusHandleScale)); }