Skip to content
This repository has been archived by the owner on May 13, 2022. It is now read-only.

Feature/hand tracking #58

Merged
merged 84 commits into from
Apr 7, 2020
Merged
Show file tree
Hide file tree
Changes from 79 commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
9bae75d
Add WMR hand controller data provider
FejZa Aug 15, 2019
657db27
Fix base class
FejZa Aug 15, 2019
897a9c8
Merge branch 'development' of https://github.com/XRTK/WindowsMixedRea…
FejZa Sep 13, 2019
0b10ccc
Merge branch 'development' of https://github.com/XRTK/WindowsMixedRea…
FejZa Sep 14, 2019
4ecb98a
Implement hand data provider interface
FejZa Sep 15, 2019
b9b52ca
Merge branch 'development' of https://github.com/XRTK/WindowsMixedRea…
FejZa Sep 19, 2019
68f2abd
Merge branch 'development' into feature/hand-tracking
FejZa Oct 1, 2019
cdf7a56
Remove obsolete WMR platform hand controller data provider
FejZa Oct 1, 2019
620ed3d
Resolve merge
FejZa Oct 31, 2019
2a8b895
Create controller stub
FejZa Oct 31, 2019
14d72bf
Remove need for hand controller data provider profile
FejZa Oct 31, 2019
b4a4934
Revert WMR speciifc hand controller
FejZa Nov 7, 2019
af92727
Merge branch 'development' of https://github.com/XRTK/WindowsMixedRea…
FejZa Nov 12, 2019
5ce2df4
Merge branch 'development' into feature/hand-tracking
FejZa Dec 19, 2019
d771a09
Create WMR profile for data provider
FejZa Dec 19, 2019
dfae688
Add WMR utilities for hand data conversion
FejZa Dec 19, 2019
11cddfc
Fix platform flag for WMR inspector
FejZa Dec 19, 2019
2c34a78
Implement WMR hand controller data provider
FejZa Dec 19, 2019
642f572
Minor refactor
FejZa Dec 19, 2019
9d9f455
Fix hand mesh observer request
FejZa Dec 19, 2019
191609f
Create controller and mapping profile + inspector
FejZa Dec 27, 2019
2a3eac8
Fix mapping naming
FejZa Dec 27, 2019
267ee09
Add required RefreshActiveControllers override to build
FejZa Dec 27, 2019
3d9dc81
Removed base hand data provider
FejZa Jan 5, 2020
055e96d
Remove reference to non existin base
FejZa Jan 5, 2020
8ffee78
Implement handjointkind extension
FejZa Jan 10, 2020
254ad3a
Extend wmr controller interface
FejZa Jan 10, 2020
f162600
Merge hand and existing controller dp and profile
FejZa Jan 10, 2020
d3bca71
Fix wmr controller dp name
FejZa Jan 10, 2020
e8b556c
Starting API upgrades
FejZa Jan 10, 2020
d7d2e43
Revert some changes
FejZa Jan 12, 2020
ad4dcad
Bring back WMR hand dp profile + inspector
FejZa Jan 12, 2020
076674a
Add WMR hc dp
FejZa Jan 12, 2020
08d78d0
Reimplement wmr hdp
FejZa Jan 12, 2020
3ed6ae2
Implement controller maangement
FejZa Jan 12, 2020
3cc4221
Convert to extensions
FejZa Jan 12, 2020
6f6f852
Fix source deteced raised twice
FejZa Jan 12, 2020
f8fe7e7
Fix WindowsMixedRealityControllerDataProvider name
FejZa Jan 12, 2020
f2b79bc
Merge branch 'feature/hand-tracking' of https://github.com/XRTK/Windo…
FejZa Jan 15, 2020
a040ef9
Fix remove all controllers
FejZa Jan 15, 2020
9f1a1bd
Merge branch 'development' of https://github.com/XRTK/WindowsMixedRea…
FejZa Jan 22, 2020
ff39f9b
Merge branch 'development' into feature/hand-tracking
FejZa Jan 22, 2020
f20c7a4
Remove WMR hand controller
FejZa Jan 23, 2020
b3a47f7
Update to MixedRealityHandController agnostic type
FejZa Jan 23, 2020
892d080
Request only speciif pointers
FejZa Jan 24, 2020
7665bdc
Remove redundant if clause
FejZa Jan 24, 2020
6a7acc6
Move conversion to converter class similar to Oculus
FejZa Jan 26, 2020
6f518db
Fix controller cleanup
FejZa Jan 26, 2020
4100644
Fix documentation copy paste error
FejZa Jan 26, 2020
16a81fa
Add missing method documentation
FejZa Jan 27, 2020
d35e738
Introduce shared hand profile configuraiton
FejZa Feb 15, 2020
eb506c4
Introduce base hand controller data provide to consume shared profile
FejZa Feb 15, 2020
afe0de0
Introduce HandMeshingEnabled profile setting
FejZa Feb 15, 2020
3ff7c00
Introduce "Hand Tracking System Profile"
FejZa Feb 18, 2020
29d066a
Merge branch 'development' into feature/hand-tracking
StephenHodgson Mar 29, 2020
0515cd3
Updated windows hand controller data provider (#54)
StephenHodgson Mar 30, 2020
11eadac
Merge branch 'development' into feature/hand-tracking
StephenHodgson Apr 1, 2020
35539ee
Added WindowsMixedRealityHandControllerDataProviderProfile
StephenHodgson Apr 1, 2020
06183e9
Fusion WMR controller dp profiles
FejZa Apr 2, 2020
f8cc34a
Housekeeping
FejZa Apr 3, 2020
2397b90
Merge branch 'development' into feature/hand-tracking
StephenHodgson Apr 3, 2020
de12aba
Merge branch 'feature/hand-tracking' of https://github.com/XRTK/Windo…
FejZa Apr 4, 2020
f9887a4
Merge branch 'development' of https://github.com/XRTK/WindowsMixedRea…
FejZa Apr 4, 2020
4ea11a6
bumped minor version
StephenHodgson Apr 4, 2020
88d12fa
bumped minor version
StephenHodgson Apr 4, 2020
877811f
Restore wmr profile and inspector
FejZa Apr 4, 2020
a72e989
Restore wmr hand profile and inspector
FejZa Apr 4, 2020
c83ab40
Restore wmr hand data provider
FejZa Apr 4, 2020
5ff3569
Shorten create asset menu path
FejZa Apr 4, 2020
e70709e
Remove hand ray type setting
FejZa Apr 4, 2020
95cd9d5
Change requests/hand tracking (#59)
StephenHodgson Apr 4, 2020
6736042
use BaseHandDataProviderProfile
StephenHodgson Apr 4, 2020
b86fce2
use BaseHandDataProvider
StephenHodgson Apr 4, 2020
18908eb
Fix compiler issues
FejZa Apr 5, 2020
0e9c219
Remove .NET scripting backend support
FejZa Apr 5, 2020
65ed236
Update since BaseHandControllerDataProvider now properly implements t…
FejZa Apr 5, 2020
d8020ec
updated extensions
StephenHodgson Apr 5, 2020
e8a02ca
a bit more organization
StephenHodgson Apr 5, 2020
be687a8
less compiler symbols
StephenHodgson Apr 5, 2020
9888522
fixed hand data provider inspector
StephenHodgson Apr 5, 2020
54d87a3
added IMixedRealityControllerDataProvider constructor param (#61)
StephenHodgson Apr 6, 2020
5e9dd94
Fixed memory issue
FejZa Apr 6, 2020
c28532f
misc formatting
StephenHodgson Apr 6, 2020
7de0f9e
Merge branch 'development' into feature/hand-tracking
StephenHodgson Apr 7, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions XRTK.WindowsMixedReality/Packages/com.xrtk.wmr/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Hand tracking support for Microsoft HoloLens 2.
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ namespace XRTK.WindowsMixedReality.Controllers
public class WindowsMixedRealityController : BaseController
{
/// <summary>
/// Constructor.
/// Controller constructor.
/// </summary>
/// <param name="trackingState"></param>
/// <param name="controllerHandedness"></param>
/// <param name="inputSource"></param>
/// <param name="interactions"></param>
/// <param name="trackingState">The controller's tracking state.</param>
/// <param name="controllerHandedness">The controller's handedness.</param>
/// <param name="inputSource">Optional input source of the controller.</param>
/// <param name="interactions">Optional controller interactions mappings.</param>
public WindowsMixedRealityController(TrackingState trackingState, Handedness controllerHandedness, IMixedRealityInputSource inputSource = null, MixedRealityInteractionMapping[] interactions = null)
: base(trackingState, controllerHandedness, inputSource, interactions)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using XRTK.Providers.Controllers.Hands;
using XRTK.WindowsMixedReality.Profiles;

#if WINDOWS_UWP

using System;
using System.Collections.Generic;
using UnityEngine;
using Windows.Perception;
using Windows.UI.Input.Spatial;
using XRTK.Definitions.Devices;
using XRTK.Definitions.Utilities;
using XRTK.Interfaces.InputSystem;
using XRTK.Services;
using XRTK.Utilities;
using XRTK.WindowsMixedReality.Extensions;
using XRTK.WindowsMixedReality.Utilities;

#endif // WINDOWS_UWP

namespace XRTK.WindowsMixedReality.Controllers
{
/// <summary>
/// The Windows Mixed Reality Data Provider for hand controller support.
/// It's responsible for converting the platform data to agnostic data the <see cref="MixedRealityHandController"/> can work with.
/// </summary>
public class WindowsMixedRealityHandControllerDataProvider : BaseHandControllerDataProvider
{
/// <summary>
/// Constructor.
/// </summary>
/// <param name="name">Name of the data provider as assigned in the configuration profile.</param>
/// <param name="priority">Data provider priority controls the order in the service registry.</param>
/// <param name="profile">Controller data provider profile assigned to the provider instance in the configuration inspector.</param>
public WindowsMixedRealityHandControllerDataProvider(string name, uint priority, WindowsMixedRealityHandControllerDataProviderProfile profile)
: base(name, priority, profile) { }

#if WINDOWS_UWP

private readonly WindowsMixedRealityHandDataConverter handDataConverter = new WindowsMixedRealityHandDataConverter();
private readonly Dictionary<uint, MixedRealityHandController> activeControllers = new Dictionary<uint, MixedRealityHandController>();

private SpatialInteractionManager spatialInteractionManager = null;

/// <summary>
/// Gets the native <see cref="Windows.UI.Input.Spatial.SpatialInteractionManager"/> instace for the current application
/// state.
/// </summary>
private SpatialInteractionManager SpatialInteractionManager
{
get
{
if (spatialInteractionManager == null)
{
UnityEngine.WSA.Application.InvokeOnUIThread(() =>
{
spatialInteractionManager = SpatialInteractionManager.GetForCurrentView();
}, true);
}

return spatialInteractionManager;
}
}

#region IMixedRealityControllerDataProvider lifecycle implementation

/// <inheritdoc/>
public override void Initialize()
{
base.Initialize();
WindowsMixedRealityHandDataConverter.HandMeshingEnabled = HandMeshingEnabled;
}

/// <inheritdoc/>
public override void Update()
{
base.Update();

// Update existing controllers or create a new one if needed.
IReadOnlyList<SpatialInteractionSourceState> sources = GetCurrentSources();
if (sources == null)
{
return;
}

for (int i = 0; i < sources.Count; i++)
{
SpatialInteractionSourceState sourceState = sources[i];
SpatialInteractionSource spatialInteractionSource = sourceState.Source;

// If we already have a controller created for this source, update it.
if (TryGetController(spatialInteractionSource.Id, out MixedRealityHandController existingController))
{
existingController.UpdateController(handDataConverter.GetHandData(sourceState));
}
else
{
// Try and create a new controller if not.
MixedRealityHandController controller = CreateController(spatialInteractionSource);
if (controller != null)
{
controller.UpdateController(handDataConverter.GetHandData(sourceState));
}
}
}

// We need to cleanup any controllers, that are not detected / tracked anymore as well.
List<uint> markedForRemoval = new List<uint>();
foreach (var controllerRegistry in activeControllers)
{
uint registeredId = controllerRegistry.Key;
for (int i = 0; i < sources.Count; i++)
{
uint currentSourceId = sources[i].Source.Id;
if (currentSourceId.Equals(registeredId))
{
// Registered controller is still active.
continue;
}

// This controller is not in the up-to-date sources list,
// so we need to remove it.
RemoveController(registeredId, false);
markedForRemoval.Add(registeredId);
}
}

for (int i = 0; i < markedForRemoval.Count; i++)
{
activeControllers.Remove(markedForRemoval[i]);
}
}

/// <inheritdoc/>
public override void Disable()
{
foreach (var controller in activeControllers)
{
RemoveController(controller.Key, false);
}

activeControllers.Clear();
base.Disable();
}

#endregion IMixedRealityControllerDataProvider lifecycle implementation

#region Controller Management

/// <summary>
/// Reads currently detected input sources by the current <see cref="SpatialInteractionManager"/> instance.
/// </summary>
/// <returns>List of sources. Can be null.</returns>
private IReadOnlyList<SpatialInteractionSourceState> GetCurrentSources()
{
// Articulated hand support is only present in the 18362 version and beyond Windows
// SDK (which contains the V8 drop of the Universal API Contract). In particular,
// the HandPose related APIs are only present on this version and above.
if (WindowsApiChecker.UniversalApiContractV8_IsAvailable && SpatialInteractionManager != null)
{
PerceptionTimestamp perceptionTimestamp = PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now);
IReadOnlyList<SpatialInteractionSourceState> sources = SpatialInteractionManager.GetDetectedSourcesAtTimestamp(perceptionTimestamp);

return sources;
}

return null;
}

/// <summary>
/// Checks whether a <see cref="MixedRealityHandController"/> has already been created and registered
/// for a given <see cref="SpatialInteractionSource"/>.
/// </summary>
/// <param name="spatialInteractionSourceId">Input source ID to lookup the controller for.</param>
/// <param name="controller">Reference to found controller, if existing.</param>
/// <returns>True, if the controller is registered and alive.</returns>
private bool TryGetController(uint spatialInteractionSourceId, out MixedRealityHandController controller)
{
if (activeControllers.ContainsKey(spatialInteractionSourceId))
{
controller = activeControllers[spatialInteractionSourceId];
Debug.Assert(controller != null, $"Controller {spatialInteractionSourceId} was not properly unregistered or unexpectedly destroyed.");
return true;
}

controller = null;
return false;
}

/// <summary>
/// Creates the controller for a new device and registers it.
/// </summary>
/// <param name="spatialInteractionSource">Source State provided by the SDK.</param>
/// <returns>New controller input source.</returns>
private MixedRealityHandController CreateController(SpatialInteractionSource spatialInteractionSource)
{
// We are creating a new controller for the source, determine the type of controller to use.
Type controllerType = spatialInteractionSource.Kind.ToControllerType();
if (controllerType == null || controllerType != typeof(MixedRealityHandController))
{
// This data provider only cares about hands.
return null;
}

// Ready to create the controller instance.
Handedness controllingHand = spatialInteractionSource.Handedness.ToHandedness();
IMixedRealityPointer[] pointers = spatialInteractionSource.IsPointingSupported ? RequestPointers(controllerType, controllingHand, true) : null;
string nameModifier = controllingHand == Handedness.None ? spatialInteractionSource.Kind.ToString() : controllingHand.ToString();
IMixedRealityInputSource inputSource = MixedRealityToolkit.InputSystem?.RequestNewGenericInputSource($"Mixed Reality Hand Controller {nameModifier}", pointers);
MixedRealityHandController detectedController = new MixedRealityHandController(TrackingState.NotApplicable, controllingHand, inputSource, null);

if (!detectedController.SetupConfiguration(controllerType))
{
// Controller failed to be setup correctly.
// Return null so we don't raise the source detected.
return null;
}

for (int i = 0; i < detectedController.InputSource?.Pointers?.Length; i++)
{
detectedController.InputSource.Pointers[i].Controller = detectedController;
}

MixedRealityToolkit.InputSystem.RaiseSourceDetected(detectedController.InputSource, detectedController);
if (MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.ControllerVisualizationProfile.RenderMotionControllers)
{
detectedController.TryRenderControllerModel(controllerType);
}

activeControllers.Add(spatialInteractionSource.Id, detectedController);
return detectedController;
}

/// <summary>
/// Removes the selected controller from the active store.
/// </summary>
/// <param name="spatialInteractionSourceId">ID of the input source to remove.</param>
/// <param name="removeFromRegistry">Should the controller be removed from the <see cref="activeControllers"/>
/// registry as well? Defaults to true.</param>
private void RemoveController(uint spatialInteractionSourceId, bool removeFromRegistry = true)
{
if (TryGetController(spatialInteractionSourceId, out MixedRealityHandController controller))
{
MixedRealityToolkit.InputSystem?.RaiseSourceLost(controller.InputSource, controller);
if (removeFromRegistry)
{
activeControllers.Remove(spatialInteractionSourceId);
}
}
}

#endregion Controller Management

#endif // WINDOWS_UWP
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) XRTK. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

#if WINDOWS_UWP

using Windows.Perception.People;
using XRTK.Definitions.Controllers.Hands;

namespace XRTK.WindowsMixedReality.Extensions
{
public static class HandJointKindExtensions
{
public static TrackedHandJoint ToTrackedHandJoint(this HandJointKind handJointKind)
{
switch (handJointKind)
{
case HandJointKind.Palm: return TrackedHandJoint.Palm;

case HandJointKind.Wrist: return TrackedHandJoint.Wrist;

case HandJointKind.ThumbMetacarpal: return TrackedHandJoint.ThumbMetacarpalJoint;
case HandJointKind.ThumbProximal: return TrackedHandJoint.ThumbProximalJoint;
case HandJointKind.ThumbDistal: return TrackedHandJoint.ThumbDistalJoint;
case HandJointKind.ThumbTip: return TrackedHandJoint.ThumbTip;

case HandJointKind.IndexMetacarpal: return TrackedHandJoint.IndexMetacarpal;
case HandJointKind.IndexProximal: return TrackedHandJoint.IndexKnuckle;
case HandJointKind.IndexIntermediate: return TrackedHandJoint.IndexMiddleJoint;
case HandJointKind.IndexDistal: return TrackedHandJoint.IndexDistalJoint;
case HandJointKind.IndexTip: return TrackedHandJoint.IndexTip;

case HandJointKind.MiddleMetacarpal: return TrackedHandJoint.MiddleMetacarpal;
case HandJointKind.MiddleProximal: return TrackedHandJoint.MiddleKnuckle;
case HandJointKind.MiddleIntermediate: return TrackedHandJoint.MiddleMiddleJoint;
case HandJointKind.MiddleDistal: return TrackedHandJoint.MiddleDistalJoint;
case HandJointKind.MiddleTip: return TrackedHandJoint.MiddleTip;

case HandJointKind.RingMetacarpal: return TrackedHandJoint.RingMetacarpal;
case HandJointKind.RingProximal: return TrackedHandJoint.RingKnuckle;
case HandJointKind.RingIntermediate: return TrackedHandJoint.RingMiddleJoint;
case HandJointKind.RingDistal: return TrackedHandJoint.RingDistalJoint;
case HandJointKind.RingTip: return TrackedHandJoint.RingTip;

case HandJointKind.LittleMetacarpal: return TrackedHandJoint.PinkyMetacarpal;
case HandJointKind.LittleProximal: return TrackedHandJoint.PinkyKnuckle;
case HandJointKind.LittleIntermediate: return TrackedHandJoint.PinkyMiddleJoint;
case HandJointKind.LittleDistal: return TrackedHandJoint.PinkyDistalJoint;
case HandJointKind.LittleTip: return TrackedHandJoint.PinkyTip;

default: return TrackedHandJoint.None;
}
}
}
}
#endif // WINDOWS_UWP

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading