11using System.Collections.Generic;
26 private Collider[][] _collidingCandidates =
new Collider[6][];
27 private int[] _numberOfColliders =
new int[6];
28 private Vector3[] _fingerTipPositions =
new Vector3[5];
29 private Vector3[] _fingerKnucklePositions =
new Vector3[5];
32 float fingerStickiness = 0F,
33 float thumbStickiness = 0.04F,
34 float maxCurl = 0.65F,
35 float minCurl = -0.1F,
36 float fingerRadius = 0.012F,
37 float thumbRadius = 0.017F,
38 float grabCooldown = 0.2F,
39 float maxCurlVel = 0.0F,
40 float grabbedMaxCurlVel = -0.025F,
41 float maxGrabDistance = 0.05F,
43 QueryTriggerInteraction queryTriggers = QueryTriggerInteraction.UseGlobal) {
47 fingerStickiness, thumbStickiness, maxCurl, minCurl, fingerRadius,
48 thumbRadius, grabCooldown, maxCurlVel, grabbedMaxCurlVel, maxGrabDistance,
52 fingerStickiness, thumbStickiness, maxCurl, minCurl, fingerRadius,
53 thumbRadius, grabCooldown, maxCurlVel, grabbedMaxCurlVel, maxGrabDistance,
57 for (
int i = 0; i < _collidingCandidates.Length; i++) {
58 _collidingCandidates[i] =
new Collider[5];
68 _scaledGrabParams.FINGERTIP_RADIUS = _defaultGrabParams.FINGERTIP_RADIUS
70 _scaledGrabParams.THUMBTIP_RADIUS = _defaultGrabParams.THUMBTIP_RADIUS
72 _scaledGrabParams.MAXIMUM_DISTANCE_FROM_HAND = _defaultGrabParams.MAXIMUM_DISTANCE_FROM_HAND
89 for (
int i = 0; i < hand.Fingers.Count; i++) {
90 _fingerTipPositions[i] = hand.Fingers[i].TipPosition.ToVector3();
91 _fingerKnucklePositions[i] = hand.Fingers[i].Bone(
Bone.
BoneType.TYPE_METACARPAL).NextJoint.ToVector3();
102 graspedObject =
null;
111 graspedObject = interactionObj;
122 releasedObject =
null;
137 private enum GraspUpdateMode {
146 private bool updateBehaviour(
IInteractionBehaviour behaviour,
Hand hand, GraspUpdateMode graspMode,
bool ignoreTemporal =
false) {
150 if (!_classifiers.TryGetValue(behaviour, out classifier)) {
152 _classifiers.Add(behaviour, classifier);
158 ref _collidingCandidates,
159 ref _numberOfColliders,
163 bool didStateChange =
false;
164 if (!classifier.prevThisControllerGrabbing && classifier.isThisControllerGrabbing
165 && graspMode == GraspUpdateMode.BeginGrasp) {
166 didStateChange =
true;
168 classifier.prevThisControllerGrabbing = classifier.isThisControllerGrabbing;
170 else if (classifier.prevThisControllerGrabbing && !classifier.isThisControllerGrabbing
172 didStateChange =
true;
174 classifier.coolDownProgress = 0f;
175 classifier.prevThisControllerGrabbing = classifier.isThisControllerGrabbing;
178 return didStateChange;
183 _classifiers.Remove(behaviour);
188 if (_classifiers.TryGetValue(behaviour, out classifier)) {
190 classifier.isThisControllerGrabbing =
false;
191 classifier.coolDownProgress = 0F;
192 for (
int i = 0; i < classifier.probes.Length; i++) {
193 classifier.probes[i].isInside =
false;
200 if (_classifiers.TryGetValue(behaviour, out classifier)) {
202 for (
int probeIdx = 0; probeIdx < classifier.probes.Length; probeIdx++) {
203 if (classifier.probes[probeIdx].isInside) {
204 fingertipPositionsBuffer[writeIdx++] = _fingerTipPositions[probeIdx];
207 numGraspingFingertips = writeIdx;
210 numGraspingFingertips = 0;
215 Debug.Log(
"HEY THIS SHOULDN'T BE BEING CALLED");
218 return updateBehaviour(intObj, hand, GraspUpdateMode.BeginGrasp,
219 ignoreTemporal:
true);
223 if (original ==
null) {
224 throw new ArgumentNullException(
"original");
227 if (replacement ==
null) {
228 throw new ArgumentNullException(
"replacement");
232 if (!_classifiers.TryGetValue(original, out classifier)) {
233 throw new InvalidOperationException(
"Cannot swap from something that is not currently grasped!");
237 classifier.transform = replacement.
transform;
239 _classifiers.Remove(original);
240 _classifiers[replacement] = classifier;
244 classifier.handChirality = hand.
IsLeft;
245 classifier.handDirection = hand.
Direction.ToVector3();
246 classifier.handXBasis = hand.
Basis.
xBasis.ToVector3();
250 + (hand.
PalmNormal * 0.01f * simScale)).ToVector3();
251 for (
int i = 0; i < hand.
Fingers.Count; i++) {
252 classifier.probes[i].direction = hand.
Fingers[i].Direction.ToVector3();
254 classifier.isGrabbed = behaviour.
isGrasped;
The Bone class represents a tracked bone.
BoneType
Enumerates the type of bones.
The Hand class reports the physical characteristics of a detected hand.
Vector Direction
The direction from the palm position toward the fingers.
LeapTransform Basis
The transform of the hand.
Vector PalmNormal
The normal vector to the palm. If your hand is flat, this vector will point downward,...
bool IsLeft
Identifies whether this Hand is a left hand.
Vector PalmPosition
The center position of the palm.
List< Finger > Fingers
The list of Finger objects detected in this frame that are attached to this hand, given in order from...
bool prevThisControllerGrabbing
static void UpdateAllProbeColliders(Vector3[] aPositions, Vector3[] bPositions, ref Collider[][] collidingCandidates, ref int[] numberOfColliders, ClassifierParameters grabParameters)
static void UpdateClassifier(GrabClassifier classifier, ClassifierParameters grabParameters, ref Collider[][] collidingCandidates, ref int[] numberOfColliders, bool ignoreTemporal=false)
ReadonlyHashSet< IInteractionBehaviour > graspCandidates
Gets the set of objects currently considered graspable.
InteractionManager manager
IInteractionBehaviour graspedObject
Gets the object the controller is currently grasping, or null if there is no such object.
bool isGraspingObject
Gets whether the controller is currently grasping an object.
override bool isTracked
Gets whether the underlying Leap hand is currently tracked.
Hand leapHand
Gets the last tracked state of the Leap hand.
float SimulationScale
A scale that can be used to appropriately transform distances that otherwise expect one Unity unit to...
int GetInteractionLayerMask()
Returns a layer mask containing all layers that might contain interaction objects.
bool TryGrasp(IInteractionBehaviour intObj, Hand hand)
bool FixedUpdateClassifierRelease(out IInteractionBehaviour releasedObject)
void FixedUpdateClassifierHandState(Transform headTransform=null)
void UnregisterInteractionBehaviour(IInteractionBehaviour behaviour)
void SwapClassifierState(IInteractionBehaviour original, IInteractionBehaviour replacement)
InteractionHand interactionHand
void GetGraspingFingertipPositions(IInteractionBehaviour behaviour, Vector3[] fingertipPositionsBuffer, out int numGraspingFingertips)
void FillClassifier(IInteractionBehaviour behaviour, Hand hand, ref GrabClassifierHeuristics.GrabClassifier classifier)
HeuristicGrabClassifier(InteractionHand intHand, float fingerStickiness=0F, float thumbStickiness=0.04F, float maxCurl=0.65F, float minCurl=-0.1F, float fingerRadius=0.012F, float thumbRadius=0.017F, float grabCooldown=0.2F, float maxCurlVel=0.0F, float grabbedMaxCurlVel=-0.025F, float maxGrabDistance=0.05F, int layerMask=0, QueryTriggerInteraction queryTriggers=QueryTriggerInteraction.UseGlobal)
void NotifyGraspForciblyReleased(IInteractionBehaviour behaviour)
bool FixedUpdateClassifierGrasp(out IInteractionBehaviour graspedObject)
IInteractionBehaviour is the interface that defines all Interaction objects, specifying the minimum s...
A utility struct for ease of use when you want to wrap a piece of code in a Profiler....