Mercurial > hg > Game > Games
diff Orchestland/Assets/LeapMotion/Scripts/Hands/HandModel.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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Orchestland/Assets/LeapMotion/Scripts/Hands/HandModel.cs Fri Jul 17 23:09:20 2015 +0900 @@ -0,0 +1,275 @@ +/******************************************************************************\ +* Copyright (C) Leap Motion, Inc. 2011-2014. * +* Leap Motion proprietary. Licensed under Apache 2.0 * +* Available at http://www.apache.org/licenses/LICENSE-2.0.html * +\******************************************************************************/ + +using UnityEngine; +using System.Collections; +using Leap; + +/** +* The base class for all hand models, both graphics and physics. +* +* This class serves as the interface between the HandController object +* and the concrete hand object containing the graphics and physics of a hand. +* +* Subclasses of HandModel must implement InitHand() and UpdateHand(). The UpdateHand() +* function is called in the Unity Update() phase for graphics HandModel instances; +* and in the Unity FixedUpdate() phase for physics objects. InitHand() is called once, +* when the hand is created and is followed by a call to UpdateHand(). +*/ +public abstract class HandModel : MonoBehaviour { + + /** The number of fingers on a hand.*/ + public const int NUM_FINGERS = 5; + + /** The model width of the hand in meters. This value is used with the measured value + * of the user's hand to scale the model proportionally. + */ + public float handModelPalmWidth = 0.085f; + /** The array of finger objects for this hand. The array is ordered from thumb (element 0) to pinky (element 4).*/ + public FingerModel[] fingers = new FingerModel[NUM_FINGERS]; + + // Unity references + public Transform palm; + public Transform forearm; + public Transform wristJoint; + public Transform elbowJoint; + + // Leap references + /** The Leap Hand object this hand model represents. */ + protected Hand hand_; + /** The parent HandController object for this hand. */ + protected HandController controller_; + + /** Whether the parent HandController instance has been set to mirror across the z axis.*/ + protected bool mirror_z_axis_ = false; + + /** + * Calculates the offset between the wrist position and the controller based + * on the HandController.handMovementScale property and the Leap hand wrist position. + */ + public Vector3 GetHandOffset() { + if (controller_ == null || hand_ == null) + return Vector3.zero; + + Vector3 additional_movement = controller_.handMovementScale - Vector3.one; + Vector3 scaled_wrist_position = Vector3.Scale(additional_movement, hand_.WristPosition.ToUnityScaled(mirror_z_axis_)); + + return controller_.transform.TransformPoint(scaled_wrist_position) - + controller_.transform.position; + } + + /** Calculates the position of the palm relative to the controller. + * @returns A Vector3 containing the Unity coordinates of the palm position. + */ + public Vector3 GetPalmPosition() { + if (controller_ != null && hand_ != null) { + return controller_.transform.TransformPoint (hand_.PalmPosition.ToUnityScaled (mirror_z_axis_)) + GetHandOffset (); + } + if (palm) { + return palm.position; + } + return Vector3.zero; + } + + /** Calculates the rotation of the hand relative to the controller. + * @returns A Quaternion representing the rotation of the hand relative to the controller. + */ + public Quaternion GetPalmRotation() { + if (controller_ != null && hand_ != null) { + return controller_.transform.rotation * hand_.Basis.Rotation(mirror_z_axis_); + } + if (palm) { + return palm.rotation; + } + return Quaternion.identity; + } + + /** Calculates the direction vector of the hand relative to the controller. + * @returns A Vector3 representing the direction of the hand relative to the controller. + */ + public Vector3 GetPalmDirection() { + if (controller_ != null && hand_ != null) { + return controller_.transform.TransformDirection(hand_.Direction.ToUnity(mirror_z_axis_)); + } + if (palm) { + return palm.forward; + } + return Vector3.forward; + } + + /** Calculates the normal vector projecting from the hand relative to the controller. + * @returns A Vector3 representing the vector perpendicular to the palm. + */ + public Vector3 GetPalmNormal() { + if (controller_ != null && hand_ != null) { + return controller_.transform.TransformDirection(hand_.PalmNormal.ToUnity(mirror_z_axis_)); + } + if (palm) { + return -palm.up; + } + return -Vector3.up; + } + + /** Calculates the direction vector of the forearm relative to the controller. + * @returns A Vector3 representing the direction of the forearm (pointing from elbow to wrist). + */ + public Vector3 GetArmDirection() { + if (controller_ != null && hand_ != null) { + return controller_.transform.TransformDirection(hand_.Arm.Direction.ToUnity(mirror_z_axis_)); + } + if (forearm) { + return forearm.forward; + } + return Vector3.forward; + } + + /** Calculates the center of the forearm relative to the controller. + * @returns A Vector3 containing the Unity coordinates of the center of the forearm. + */ + public Vector3 GetArmCenter() { + if (controller_ != null && hand_ != null) { + Vector leap_center = 0.5f * (hand_.Arm.WristPosition + hand_.Arm.ElbowPosition); + return controller_.transform.TransformPoint (leap_center.ToUnityScaled (mirror_z_axis_)) + GetHandOffset (); + } + if (forearm) { + return forearm.position; + } + return Vector3.zero; + } + + /** Returns the measured length of the forearm in meters.*/ + public float GetArmLength() { + return (hand_.Arm.WristPosition - hand_.Arm.ElbowPosition).Magnitude * UnityVectorExtension.INPUT_SCALE; + } + + /** Returns the measured width of the forearm in meters.*/ + public float GetArmWidth() { + return hand_.Arm.Width * UnityVectorExtension.INPUT_SCALE; + } + + /** Calculates the position of the elbow relative to the controller. + * @returns A Vector3 containing the Unity coordinates of the elbow. + */ + public Vector3 GetElbowPosition() { + if (controller_ != null && hand_ != null) { + Vector3 local_position = hand_.Arm.ElbowPosition.ToUnityScaled (mirror_z_axis_); + return controller_.transform.TransformPoint (local_position) + GetHandOffset (); + } + if (elbowJoint) { + return elbowJoint.position; + } + return Vector3.zero; + } + + /** Calculates the position of the wrist relative to the controller. + * @returns A Vector3 containing the Unity coordinates of the wrist. + */ + public Vector3 GetWristPosition() { + if (controller_ != null && hand_ != null) { + Vector3 local_position = hand_.Arm.WristPosition.ToUnityScaled (mirror_z_axis_); + return controller_.transform.TransformPoint (local_position) + GetHandOffset (); + } + if (wristJoint) { + return wristJoint.position; + } + return Vector3.zero; + } + + /** Calculates the rotation of the forearm relative to the controller. + * @returns A Quaternion representing the rotation of the arm relative to the controller. + */ + public Quaternion GetArmRotation() { + if (controller_ != null && hand_ != null) { + Quaternion local_rotation = hand_.Arm.Basis.Rotation (mirror_z_axis_); + return controller_.transform.rotation * local_rotation; + } + if (forearm) { + return forearm.rotation; + } + return Quaternion.identity; + } + + /** + * Returns the Leap Hand object represented by this HandModel. + * Note that any physical quantities and directions obtained from the + * Leap Hand object are relative to the Leap Motion coordinate system, + * which uses a right-handed axes and units of millimeters. + */ + public Hand GetLeapHand() { + return hand_; + } + + /** + * Assigns a Leap Hand object to this hand model. + * Note that the Leap Hand objects are recreated every frame. The parent + * HandController calls this method to set or update the underlying hand. + */ + public void SetLeapHand(Hand hand) { + hand_ = hand; + for (int i = 0; i < fingers.Length; ++i) { + if (fingers[i] != null) { + fingers[i].SetLeapHand(hand_); + fingers[i].SetOffset(GetHandOffset()); + } + } + } + + /** + * Sets the mirror z-axis flag for this Hand Model and its fingers. + * Mirroring the z axis reverses the hand so that they face the opposite direction -- as if in a mirror. + * @param mirror Set true, the default value to mirror; false for normal rendering. + */ + public void MirrorZAxis(bool mirror = true) { + mirror_z_axis_ = mirror; + for (int i = 0; i < fingers.Length; ++i) { + if (fingers[i] != null) + fingers[i].MirrorZAxis(mirror); + } + } + + /** Whether this hand is currently mirrored.*/ + public bool IsMirrored() { + return mirror_z_axis_; + } + + /** The parent HandController object of this hand.*/ + public HandController GetController() { + return controller_; + } + + /** Sets the parent HandController object. */ + public void SetController(HandController controller) { + controller_ = controller; + for (int i = 0; i < fingers.Length; ++i) { + if (fingers[i] != null) + fingers[i].SetController(controller_); + } + } + + /** + * Implement this function to initialise this hand after it is created. + * This function is called by the HandController during the Unity Update() phase when a new hand is detected + * by the Leap Motion device. + */ + public virtual void InitHand() { + for (int f = 0; f < fingers.Length; ++f) { + if (fingers[f] != null) { + fingers[f].fingerType = (Finger.FingerType)f; + fingers[f].InitFinger(); + } + } + + UpdateHand (); + } + + /** + * Implement this function to update this hand once every game loop. + * For HandModel instances assigned to the HandController graphics hand list, the HandController calls this + * function during the Unity Update() phase. For HandModel instances in the physics hand list, the HandController + * calls this function in the FixedUpdate() phase. + */ + public abstract void UpdateHand(); +}