/// <summary> /// Adds the joint poses calculated from the Leap Motion Controller to the jointPoses Dictionary. /// </summary> private void SetJointPoses() { foreach (TrackedHandJoint joint in TrackedHandJointEnum) { if (attachmentHand != null && attachmentHand.isTracked) { // Is the current joint a metacarpal bool isMetacarpal = metacarpals.Contains(joint); // AttachmentPointFlags does not include metacarpals. if (isMetacarpal) { MixedRealityPose metacarpalPose = GetMetacarpalPose(joint); jointPoses[joint] = metacarpalPose; } else { AttachmentPointFlags leapAttachmentFlag = ConvertMRTKJointToLeapJoint(joint); // Get the pose of the leap joint AttachmentPointBehaviour leapJoint = attachmentHand.GetBehaviourForPoint(leapAttachmentFlag); // Set the pose calculated by the leap motion to a mixed reality pose MixedRealityPose pose = new MixedRealityPose(leapJoint.transform.position, leapJoint.transform.rotation); jointPoses[joint] = pose; } } else { jointPoses[joint] = MixedRealityPose.ZeroIdentity; } } }
// Takes advantage of two's complement representation for negative integers // to check whether the bit field has a single bit set. // https://en.wikipedia.org/wiki/Two%27s_complement public static bool IsSinglePoint(this AttachmentPointFlags points) { int mask = (int)points; bool isSingleBitSet = mask != 0 && mask == (mask & -mask); return(isSingleBitSet); }
private void makeAttachmentPointsToggle(string attachmentFlagName, Vector2 offCenterPosImgSpace) { AttachmentPointFlags attachmentPoints = target.attachmentPoints; AttachmentPointFlags flag = (AttachmentPointFlags)System.Enum.Parse(typeof(AttachmentPointFlags), attachmentFlagName, true); if (EditorGUI.Toggle(makeToggleRect(_handTexRect.center + new Vector2(offCenterPosImgSpace.x * _handTexRect.width, offCenterPosImgSpace.y * _handTexRect.height)), (attachmentPoints & flag) == flag)) { target.attachmentPoints = attachmentPoints | flag; // Set flag bit to 1. } else { if (!wouldFlagDeletionDestroyData(target, flag) || EditorUtility.DisplayDialog("Delete " + flag + " Attachment Point?", "Deleting the " + flag + " attachment point will destroy " + "its GameObject and any of its non-Attachment-Point children, " + "and will remove any components attached to it.", "Delete " + flag + " Attachment Point", "Cancel")) { target.attachmentPoints = attachmentPoints & (~flag); // Set flag bit to 0. } } }
void OnValidate() { if (!attachmentPoint.IsSinglePoint() && attachmentPoint != AttachmentPointFlags.None) { Debug.LogError("AttachmentPointBehaviours should refer to a single attachmentPoint flag.", this.gameObject); attachmentPoint = AttachmentPointFlags.None; } }
/// <summary> /// Returns whether these AttachmentPointFlags contain the flags set in otherPoints. /// </summary> /// <param name="points"></param> /// <param name="otherPoints"></param> /// <returns></returns> public static bool Contains(this AttachmentPointFlags points, AttachmentPointFlags otherPoints) { if (points == AttachmentPointFlags.None || otherPoints == AttachmentPointFlags.None) { return(false); } return((points & otherPoints) == otherPoints); }
public void refreshAttachmentTransforms(AttachmentPointFlags points) { if (_attachmentPointFlagConstants == null || _attachmentPointFlagConstants.Length == 0) { initializeAttachmentPointFlagConstants(); } // First just _check_ whether we'll need to do any destruction or creation bool requiresDestructionOrCreation = false; foreach (var flag in _attachmentPointFlagConstants) { if (flag == AttachmentPointFlags.None) { continue; } if ((!points.Contains(flag) && GetBehaviourForPoint(flag) != null) || (points.Contains(flag) && GetBehaviourForPoint(flag) == null)) { requiresDestructionOrCreation = true; } } // Go through the work of flattening and rebuilding if it is necessary. if (requiresDestructionOrCreation) { // Remove parent-child relationships so deleting parent Transforms doesn't annihilate // child Transforms that don't need to be deleted themselves. flattenAttachmentTransformHierarchy(); foreach (AttachmentPointFlags flag in _attachmentPointFlagConstants) { if (flag == AttachmentPointFlags.None) { continue; } if (points.Contains(flag)) { ensureTransformExists(flag); } else { ensureTransformDoesNotExist(flag); } } // Organize transforms, restoring parent-child relationships. organizeAttachmentTransforms(); } if (_attachmentPointsDirty) { OnAttachmentPointsModified(); _attachmentPointsDirty = false; } }
/// <summary> /// Returns whether these AttachmentPointsFlags contain the single flag specified by singlePoint. /// Will raise a warning in the editor if the argument is not a single flag constant. /// </summary> public static bool ContainsPoint(this AttachmentPointFlags points, AttachmentPointFlags singlePoint) { #if UNITY_EDITOR // Validation for ensuring singlePoint is really a single point. if (!singlePoint.IsSinglePoint()) { Debug.LogWarning("'ContainsPoint' called with an argument that contains more than one attachment point flag set."); } #endif return(points.Contains(singlePoint)); }
private void setBehaviourForPoint(AttachmentPointFlags singlePoint, AttachmentPointBehaviour behaviour) { switch (singlePoint) { case AttachmentPointFlags.None: break; case AttachmentPointFlags.Wrist: wrist = behaviour; break; case AttachmentPointFlags.Palm: palm = behaviour; break; case AttachmentPointFlags.ThumbProximalJoint: thumbProximalJoint = behaviour; break; case AttachmentPointFlags.ThumbDistalJoint: thumbDistalJoint = behaviour; break; case AttachmentPointFlags.ThumbTip: thumbTip = behaviour; break; case AttachmentPointFlags.IndexKnuckle: indexKnuckle = behaviour; break; case AttachmentPointFlags.IndexMiddleJoint: indexMiddleJoint = behaviour; break; case AttachmentPointFlags.IndexDistalJoint: indexDistalJoint = behaviour; break; case AttachmentPointFlags.IndexTip: indexTip = behaviour; break; case AttachmentPointFlags.MiddleKnuckle: middleKnuckle = behaviour; break; case AttachmentPointFlags.MiddleMiddleJoint: middleMiddleJoint = behaviour; break; case AttachmentPointFlags.MiddleDistalJoint: middleDistalJoint = behaviour; break; case AttachmentPointFlags.MiddleTip: middleTip = behaviour; break; case AttachmentPointFlags.RingKnuckle: ringKnuckle = behaviour; break; case AttachmentPointFlags.RingMiddleJoint: ringMiddleJoint = behaviour; break; case AttachmentPointFlags.RingDistalJoint: ringDistalJoint = behaviour; break; case AttachmentPointFlags.RingTip: ringTip = behaviour; break; case AttachmentPointFlags.PinkyKnuckle: pinkyKnuckle = behaviour; break; case AttachmentPointFlags.PinkyMiddleJoint: pinkyMiddleJoint = behaviour; break; case AttachmentPointFlags.PinkyDistalJoint: pinkyDistalJoint = behaviour; break; case AttachmentPointFlags.PinkyTip: pinkyTip = behaviour; break; } #if UNITY_EDITOR EditorUtility.SetDirty(this); #endif }
/// <summary> /// Returns the AttachmentPointBehaviour child object of this AttachmentHand given a /// reference to a single AttachmentPointFlags flag, or null if there is no such child object. /// </summary> public AttachmentPointBehaviour GetBehaviourForPoint(AttachmentPointFlags singlePoint) { AttachmentPointBehaviour behaviour = null; switch (singlePoint) { case AttachmentPointFlags.None: break; case AttachmentPointFlags.Wrist: behaviour = wrist; break; case AttachmentPointFlags.Palm: behaviour = palm; break; case AttachmentPointFlags.ThumbProximalJoint: behaviour = thumbProximalJoint; break; case AttachmentPointFlags.ThumbDistalJoint: behaviour = thumbDistalJoint; break; case AttachmentPointFlags.ThumbTip: behaviour = thumbTip; break; case AttachmentPointFlags.IndexKnuckle: behaviour = indexKnuckle; break; case AttachmentPointFlags.IndexMiddleJoint: behaviour = indexMiddleJoint; break; case AttachmentPointFlags.IndexDistalJoint: behaviour = indexDistalJoint; break; case AttachmentPointFlags.IndexTip: behaviour = indexTip; break; case AttachmentPointFlags.MiddleKnuckle: behaviour = middleKnuckle; break; case AttachmentPointFlags.MiddleMiddleJoint: behaviour = middleMiddleJoint; break; case AttachmentPointFlags.MiddleDistalJoint: behaviour = middleDistalJoint; break; case AttachmentPointFlags.MiddleTip: behaviour = middleTip; break; case AttachmentPointFlags.RingKnuckle: behaviour = ringKnuckle; break; case AttachmentPointFlags.RingMiddleJoint: behaviour = ringMiddleJoint; break; case AttachmentPointFlags.RingDistalJoint: behaviour = ringDistalJoint; break; case AttachmentPointFlags.RingTip: behaviour = ringTip; break; case AttachmentPointFlags.PinkyKnuckle: behaviour = pinkyKnuckle; break; case AttachmentPointFlags.PinkyMiddleJoint: behaviour = pinkyMiddleJoint; break; case AttachmentPointFlags.PinkyDistalJoint: behaviour = pinkyDistalJoint; break; case AttachmentPointFlags.PinkyTip: behaviour = pinkyTip; break; } return(behaviour); }
private void ensureTransformExists(AttachmentPointFlags singlePoint) { if (!singlePoint.IsSinglePoint()) { Debug.LogError("Tried to ensure transform exists for singlePoint, but it contains more than one set flag."); return; } AttachmentPointBehaviour pointBehaviour = GetBehaviourForPoint(singlePoint); if (pointBehaviour == null) { // First, see if there's already one in the hierarchy! Might exist due to, e.g. an Undo operation var existingPointBehaviour = this.gameObject.GetComponentsInChildren <AttachmentPointBehaviour>() .Query() .FirstOrDefault(p => p.attachmentPoint == singlePoint); // Only make a new object if the transform really doesn't exist. if (existingPointBehaviour == AttachmentPointFlags.None) { GameObject obj = new GameObject(Enum.GetName(typeof(AttachmentPointFlags), singlePoint)); #if UNITY_EDITOR Undo.RegisterCreatedObjectUndo(obj, "Created Object"); pointBehaviour = Undo.AddComponent <AttachmentPointBehaviour>(obj); #else pointBehaviour = obj.AddComponent <AttachmentPointBehaviour>(); #endif } else { pointBehaviour = existingPointBehaviour; } #if UNITY_EDITOR Undo.RecordObject(pointBehaviour, "Set Attachment Point"); #endif pointBehaviour.attachmentPoint = singlePoint; pointBehaviour.attachmentHand = this; setBehaviourForPoint(singlePoint, pointBehaviour); SetTransformParent(pointBehaviour.transform, this.transform); _attachmentPointsDirty = true; #if UNITY_EDITOR EditorUtility.SetDirty(this); #endif } }
private static bool wouldFlagDeletionDestroyData(AttachmentHands target, AttachmentPointFlags flag) { if (target.attachmentHands == null) { return(false); } foreach (var attachmentHand in target.attachmentHands) { var point = attachmentHand.GetBehaviourForPoint(flag); if (point == null) { return(false); } else { // Data will be destroyed if this AttachmentPointBehaviour's Transform contains any children // that are not themselves AttachmentPointBehaviours. foreach (var child in point.transform.GetChildren()) { if (child.GetComponent <AttachmentPointBehaviour>() == null) { return(true); } } // Data will be destroyed if this AttachmentPointBehaviour contains any components // that aren't constructed automatically. foreach (var component in point.gameObject.GetComponents <Component>()) { if (component is Transform) { continue; } if (component is AttachmentPointBehaviour) { continue; } return(true); } } } return(false); }
private void ensureTransformDoesNotExist(AttachmentPointFlags singlePoint) { if (!singlePoint.IsSinglePoint()) { Debug.LogError("Tried to ensure transform exists for singlePoint, but it contains more than one set flag"); return; } var pointBehaviour = GetBehaviourForPoint(singlePoint); if (pointBehaviour != null) { InternalUtility.Destroy(pointBehaviour.gameObject); setBehaviourForPoint(singlePoint, null); pointBehaviour = null; _attachmentPointsDirty = true; #if UNITY_EDITOR EditorUtility.SetDirty(this); #endif } }
public static void GetLeapHandPointData(Leap.Hand hand, AttachmentPointFlags singlePoint, out Vector3 position, out Quaternion rotation) { position = Vector3.zero; rotation = Quaternion.identity; if (singlePoint != AttachmentPointFlags.None && !singlePoint.IsSinglePoint()) { Debug.LogError("Cannot get attachment point data for an AttachmentPointFlags argument consisting of more than one set flag."); return; } switch (singlePoint) { case AttachmentPointFlags.None: return; case AttachmentPointFlags.Wrist: position = hand.WristPosition.ToVector3(); rotation = hand.Arm.Basis.rotation.ToQuaternion(); break; case AttachmentPointFlags.Palm: position = hand.PalmPosition.ToVector3(); rotation = hand.Basis.rotation.ToQuaternion(); break; case AttachmentPointFlags.ThumbProximalJoint: position = hand.Fingers[0].bones[1].NextJoint.ToVector3(); rotation = hand.Fingers[0].bones[2].Rotation.ToQuaternion(); break; case AttachmentPointFlags.ThumbDistalJoint: position = hand.Fingers[0].bones[2].NextJoint.ToVector3(); rotation = hand.Fingers[0].bones[3].Rotation.ToQuaternion(); break; case AttachmentPointFlags.ThumbTip: position = hand.Fingers[0].bones[3].NextJoint.ToVector3(); rotation = hand.Fingers[0].bones[3].Rotation.ToQuaternion(); break; case AttachmentPointFlags.IndexKnuckle: position = hand.Fingers[1].bones[0].NextJoint.ToVector3(); rotation = hand.Fingers[1].bones[1].Rotation.ToQuaternion(); break; case AttachmentPointFlags.IndexMiddleJoint: position = hand.Fingers[1].bones[1].NextJoint.ToVector3(); rotation = hand.Fingers[1].bones[2].Rotation.ToQuaternion(); break; case AttachmentPointFlags.IndexDistalJoint: position = hand.Fingers[1].bones[2].NextJoint.ToVector3(); rotation = hand.Fingers[1].bones[3].Rotation.ToQuaternion(); break; case AttachmentPointFlags.IndexTip: position = hand.Fingers[1].bones[3].NextJoint.ToVector3(); rotation = hand.Fingers[1].bones[3].Rotation.ToQuaternion(); break; case AttachmentPointFlags.MiddleKnuckle: position = hand.Fingers[2].bones[0].NextJoint.ToVector3(); rotation = hand.Fingers[2].bones[1].Rotation.ToQuaternion(); break; case AttachmentPointFlags.MiddleMiddleJoint: position = hand.Fingers[2].bones[1].NextJoint.ToVector3(); rotation = hand.Fingers[2].bones[2].Rotation.ToQuaternion(); break; case AttachmentPointFlags.MiddleDistalJoint: position = hand.Fingers[2].bones[2].NextJoint.ToVector3(); rotation = hand.Fingers[2].bones[3].Rotation.ToQuaternion(); break; case AttachmentPointFlags.MiddleTip: position = hand.Fingers[2].bones[3].NextJoint.ToVector3(); rotation = hand.Fingers[2].bones[3].Rotation.ToQuaternion(); break; case AttachmentPointFlags.RingKnuckle: position = hand.Fingers[3].bones[0].NextJoint.ToVector3(); rotation = hand.Fingers[3].bones[1].Rotation.ToQuaternion(); break; case AttachmentPointFlags.RingMiddleJoint: position = hand.Fingers[3].bones[1].NextJoint.ToVector3(); rotation = hand.Fingers[3].bones[2].Rotation.ToQuaternion(); break; case AttachmentPointFlags.RingDistalJoint: position = hand.Fingers[3].bones[2].NextJoint.ToVector3(); rotation = hand.Fingers[3].bones[3].Rotation.ToQuaternion(); break; case AttachmentPointFlags.RingTip: position = hand.Fingers[3].bones[3].NextJoint.ToVector3(); rotation = hand.Fingers[3].bones[3].Rotation.ToQuaternion(); break; case AttachmentPointFlags.PinkyKnuckle: position = hand.Fingers[4].bones[0].NextJoint.ToVector3(); rotation = hand.Fingers[4].bones[1].Rotation.ToQuaternion(); break; case AttachmentPointFlags.PinkyMiddleJoint: position = hand.Fingers[4].bones[1].NextJoint.ToVector3(); rotation = hand.Fingers[4].bones[2].Rotation.ToQuaternion(); break; case AttachmentPointFlags.PinkyDistalJoint: position = hand.Fingers[4].bones[2].NextJoint.ToVector3(); rotation = hand.Fingers[4].bones[3].Rotation.ToQuaternion(); break; case AttachmentPointFlags.PinkyTip: position = hand.Fingers[4].bones[3].NextJoint.ToVector3(); rotation = hand.Fingers[4].bones[3].Rotation.ToQuaternion(); break; } }