Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
using Leap.Unity.Geometry;
using Leap.Unity.Gestures;
using Leap.Unity.Infix;
using Leap.Unity.Interaction;
using Leap.Unity.Query;
using UnityEngine;
namespace Leap.Unity.AR.Testing {
using Collision = Leap.Unity.Geometry.Collision;
public class PanelPullBar : MonoBehaviour {
public InteractionBehaviour intObj; // used for closest hovering hand.
public PinchGesture pinchGesture;
public CapsuleCollider barCapsule;
public float beginHoldDist = 0.10f;
public Transform slideTransform = null;
private Matrix4x4 slideMatrix { get { return slideTransform.localToWorldMatrix; } }
private Matrix4x4 slideMatrixInv { get { return slideTransform.worldToLocalMatrix; } }
private float _slideHeldSpeed = 80f;
public float slideBackSpeed = 20f;
/// <summary>
/// The axis in slide-local space along which sliding is allowed.
/// </summary>
private Vector3 slideAxis_slide = Vector3.right;
/// <summary>
/// The maximum distance from "zero" in slide-local space to which sliding is allowed.
/// </summary>
public float maxDistance_slide = 0.2f;
public float stayOpenDistance_slide = 0.17f;
/// <summary>
/// Farthest point along the slide, in slide-local space.
/// </summary>
public Vector3 maxSlidePos_slide {
get {
return slideAxis_slide * maxDistance_slide;
}
}
private Vector3 holdOffset_slide = Vector3.zero;
/// <summary>
/// LocalSegment3 in slide-local space defining the line segment along which this
/// component's Transform is allowed to slide.
/// </summary>
public LocalSegment3 slideSegment_slide {
get {
return new LocalSegment3(Vector3.zero, maxSlidePos_slide);
}
}
public HingeElement[] hingeButtons;
private bool _isHeld = false;
private bool _isLockedOpen = false;
private void Reset() {
if (intObj == null) intObj = GetComponent<InteractionBehaviour>();
}
private void OnValidate() {
stayOpenDistance_slide = Mathf.Min(stayOpenDistance_slide, maxDistance_slide);
}
private void Start() {
stayOpenDistance_slide = Mathf.Min(stayOpenDistance_slide, maxDistance_slide);
if (intObj == null) intObj = GetComponent<InteractionBehaviour>();
}
private void Update() {
//var isInteractingWithAButton = hingeButtons.Query().Any(b => b.isInteracting);
// Determine whether to begin or end the held state this frame.
var shouldBeginHolding = false;
var interactingHand = intObj.closestHoveringHand;
if (interactingHand != null) {
if (pinchGesture.wasActivated) {
var pinchPos = pinchGesture.pose.position;
Vector3 barSegmentA, barSegmentB;
barCapsule.GetCapsulePoints(out barSegmentA, out barSegmentB);
var barPinchSqrDist = Geometry.Collision.SqrDistPointSegment(barSegmentA,
barSegmentB, pinchPos);
if (barPinchSqrDist < beginHoldDist * beginHoldDist) {
shouldBeginHolding = true;
}
}
}
var shouldStopHolding = !pinchGesture.isActive;
// Update grasped or released state of the slide.
if (!_isHeld && shouldBeginHolding) {
// Just grasped.
_isHeld = true;
var slidePos_slide = slideMatrixInv.MultiplyPoint3x4(this.transform.position);
var holdPos_slide = slideMatrixInv.MultiplyPoint3x4(pinchGesture.pose.position);
holdOffset_slide = slidePos_slide - holdPos_slide;
}
if (_isHeld && shouldStopHolding) {
// Just released.
_isHeld = false;
// Lock the slide open if released while fully open.
var pos = this.transform.position;
var pos_slide = slideMatrixInv.MultiplyPoint3x4(pos);
float slideT;
var clampedPos_slide
= Collision.ClosestPtPointSegment(slideSegment_slide, pos_slide, out slideT);
var slideDistance_slide = clampedPos_slide.Dot(slideAxis_slide);
_isLockedOpen = slideDistance_slide >= stayOpenDistance_slide;
}
// Slide the pull bar to match the held position or its target rest position.
if (_isHeld) {
var pinchPos = pinchGesture.pose.position;
var heldPosition_slide = slideMatrixInv.MultiplyPoint3x4(pinchPos);
heldPosition_slide += holdOffset_slide;
var clampedPosition_slide
= Collision.ClosestPtPointSegment(slideSegment_slide, heldPosition_slide);
var targetPos = slideMatrix.MultiplyPoint3x4(clampedPosition_slide);
this.transform.position = Vector3.Lerp(this.transform.position, targetPos,
(_slideHeldSpeed * Time.deltaTime));
}
else {
var targetPosition = slideTransform.position;
if (_isLockedOpen) {
targetPosition = slideMatrix.MultiplyPoint3x4(maxSlidePos_slide);
}
this.transform.position = Vector3.Lerp(this.transform.position, targetPosition,
slideBackSpeed * Time.deltaTime);
}
}
#region Archive -- segment 2 segment for basic pinch data
///// <summary>
///// Returns the smallest _squared_ pinch distance (pinching the thumb) of the hand,
///// checking the index, middle, and ring fingers.
/////
///// Pinching is checked against the last thumb segment and the last two finger
///// segments of each finger. The point on the finger for the closest pinch distance
///// is output to a, and the point on the thumb for the pinch is output to b.
///// </summary>
//private static float getPinchDistance(Hand hand, out Vector3 a, out Vector3 b) {
// Finger index = hand.GetIndex(), middle = hand.GetMiddle(), ring = hand.GetRing();
// Vector3 index_indexP, index_thumbP, middle_middleP, middle_thumbP,
// ring_ringP, ring_thumbP;
// var indexSqrDist
// = getFingerPinchDistance(hand, index, out index_indexP, out index_thumbP);
// var middleSqrDist
// = getFingerPinchDistance(hand, middle, out middle_middleP, out middle_thumbP);
// var ringSqrDist
// = getFingerPinchDistance(hand, ring, out ring_ringP, out ring_thumbP);
// float[] dists = { indexSqrDist, middleSqrDist, ringSqrDist };
// Vector3[] indexPs = { index_indexP, index_thumbP };
// Vector3[] middlePs = { middle_middleP, middle_thumbP };
// Vector3[] ringPs = { ring_ringP, ring_thumbP };
// Vector3[][] Ps = { indexPs, middlePs, ringPs };
// float smallestDist = float.PositiveInfinity; int smallestIdx = -1;
// for (int i = 0; i < dists.Length; i++) {
// var testDist = dists[i];
// if (smallestIdx == -1 || smallestDist == float.PositiveInfinity
// || testDist < smallestDist) {
// smallestDist = testDist;
// smallestIdx = i;
// }
// }
// a = Ps[smallestIdx][0];
// b = Ps[smallestIdx][1];
// return smallestDist;
//}
///// <summary>
///// Checks pinch distance against the last two bones of the argument finger and
///// the last bone of the thumb, returns the squared distance between the two closest
///// finger-and-thumb segments, and outputs the closest positions on each segment.
///// </summary>
//private static float getFingerPinchDistance(Hand hand, Finger finger,
// out Vector3 fingerP, out Vector3 thumbP) {
// var thumb = hand.GetThumb();
// var fingerSegBone1 = finger.bones[3];
// var fingerSegment1 = new LocalSegment3(fingerSegBone1.PrevJoint.ToVector3(),
// fingerSegBone1.NextJoint.ToVector3());
// var fingerSegBone2 = finger.bones[2];
// var fingerSegment2 = new LocalSegment3(fingerSegBone2.PrevJoint.ToVector3(),
// fingerSegBone2.NextJoint.ToVector3());
// var thumbSegBone = thumb.bones[3];
// var thumbSegment = new LocalSegment3(thumbSegBone.PrevJoint.ToVector3(),
// thumbSegBone.NextJoint.ToVector3());
// Vector3 fingerP1, thumbP1;
// float fingerT1, thumbT1;
// var sqrDist1 = Leap.Unity.Geometry.Collision.Intersect(fingerSegment1, thumbSegment,
// out fingerT1, out thumbT1, out fingerP1, out thumbP1);
// Vector3 fingerP2, thumbP2;
// float fingerT2, thumbT2;
// var sqrDist2 = Leap.Unity.Geometry.Collision.Intersect(fingerSegment2, thumbSegment,
// out fingerT2, out thumbT2, out fingerP2, out thumbP2);
// if (sqrDist1 <= sqrDist2) {
// fingerP = fingerP1; thumbP = thumbP1;
// return sqrDist1;
// }
// else {
// fingerP = fingerP2; thumbP = thumbP2;
// return sqrDist2;
// }
//}
#endregion
}
}
d2871d28eThis file is pinned to the selected release. Download the original to open it in your design tool.