comparison Orchestland/Assets/LeapMotion/Scripts/Utils/MagneticPinch.cs @ 1:f7675884f2a1

Add Orchestland project
author Daiki OYAKAWA <e135764@ie.u-ryukyu.ac.jp>
date Fri, 17 Jul 2015 23:09:20 +0900
parents
children
comparison
equal deleted inserted replaced
0:347d21cdfc22 1:f7675884f2a1
1 /******************************************************************************\
2 * Copyright (C) Leap Motion, Inc. 2011-2014. *
3 * Leap Motion proprietary. Licensed under Apache 2.0 *
4 * Available at http://www.apache.org/licenses/LICENSE-2.0.html *
5 \******************************************************************************/
6
7 using UnityEngine;
8 using System.Collections;
9 using Leap;
10
11 /**
12 * Detects pinches and grabs the closest rigidbody if it's within a given range.
13 *
14 * Attach this script to the physics hand object assinged to the HandController in a scene.
15 */
16 public class MagneticPinch : MonoBehaviour {
17
18 public const float TRIGGER_DISTANCE_RATIO = 0.7f;
19
20 /** The stiffness of the spring force used to move the object toward the hand. */
21 public float forceSpringConstant = 100.0f;
22 /** The maximum range at which an object can be picked up.*/
23 public float magnetDistance = 2.0f;
24
25 protected bool pinching_;
26 protected Collider grabbed_;
27
28 void Start() {
29 pinching_ = false;
30 grabbed_ = null;
31 }
32
33 /** Finds an object to grab and grabs it. */
34 void OnPinch(Vector3 pinch_position) {
35 pinching_ = true;
36
37 // Check if we pinched a movable object and grab the closest one that's not part of the hand.
38 Collider[] close_things = Physics.OverlapSphere(pinch_position, magnetDistance);
39 Vector3 distance = new Vector3(magnetDistance, 0.0f, 0.0f);
40
41 for (int j = 0; j < close_things.Length; ++j) {
42 Vector3 new_distance = pinch_position - close_things[j].transform.position;
43 if (close_things[j].GetComponent<Rigidbody>() != null && new_distance.magnitude < distance.magnitude &&
44 !close_things[j].transform.IsChildOf(transform)) {
45 grabbed_ = close_things[j];
46 distance = new_distance;
47 }
48 }
49 }
50
51 /** Clears the pinch state. */
52 void OnRelease() {
53 grabbed_ = null;
54 pinching_ = false;
55 }
56
57 /**
58 * Checks whether the hand is pinching and updates the position of the pinched object.
59 */
60 void Update() {
61 bool trigger_pinch = false;
62 HandModel hand_model = GetComponent<HandModel>();
63 Hand leap_hand = hand_model.GetLeapHand();
64
65 if (leap_hand == null)
66 return;
67
68 // Scale trigger distance by thumb proximal bone length.
69 Vector leap_thumb_tip = leap_hand.Fingers[0].TipPosition;
70 float proximal_length = leap_hand.Fingers[0].Bone(Bone.BoneType.TYPE_PROXIMAL).Length;
71 float trigger_distance = proximal_length * TRIGGER_DISTANCE_RATIO;
72
73 // Check thumb tip distance to joints on all other fingers.
74 // If it's close enough, start pinching.
75 for (int i = 1; i < HandModel.NUM_FINGERS && !trigger_pinch; ++i) {
76 Finger finger = leap_hand.Fingers[i];
77
78 for (int j = 0; j < FingerModel.NUM_BONES && !trigger_pinch; ++j) {
79 Vector leap_joint_position = finger.Bone((Bone.BoneType)j).NextJoint;
80 if (leap_joint_position.DistanceTo(leap_thumb_tip) < trigger_distance)
81 trigger_pinch = true;
82 }
83 }
84
85 Vector3 pinch_position = hand_model.fingers[0].GetTipPosition();
86
87 // Only change state if it's different.
88 if (trigger_pinch && !pinching_)
89 OnPinch(pinch_position);
90 else if (!trigger_pinch && pinching_)
91 OnRelease();
92
93 // Accelerate what we are grabbing toward the pinch.
94 if (grabbed_ != null) {
95 Vector3 distance = pinch_position - grabbed_.transform.position;
96 grabbed_.GetComponent<Rigidbody>().AddForce(forceSpringConstant * distance);
97 }
98 }
99 }