Skip to content

Commit 48ec119

Browse files
authored
Merge pull request #9425 from microsoft/releases/2.6.0
Merge Releases/2.6.0 -> mrtk_release
2 parents 8a9d151 + 6ec5bb4 commit 48ec119

File tree

1,381 files changed

+126398
-117408
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,381 files changed

+126398
-117408
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ MSBuildForUnity.Common.props
105105
*.msb4u.sln.meta
106106
Dependencies*
107107
Nuget.config*
108+
*.obj
109+
*.bin
108110

109111
# =========== #
110112
# Other files #

Assets/MRTK/Core/Attributes/MixedRealityControllerAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace Microsoft.MixedReality.Toolkit.Input
1515
/// <summary>
1616
/// Attach to a controller device class to make it show up in the controller mapping profile.
1717
/// </summary>
18-
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
18+
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
1919
public class MixedRealityControllerAttribute : Attribute
2020
{
2121
/// <summary>

Assets/MRTK/Core/Attributes/MixedRealityServiceProfileAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public MixedRealityServiceProfileAttribute(Type requiredType, Type excludedType
2222
public MixedRealityServiceProfileAttribute(Type[] requiredTypes, Type[] excludedTypes = null)
2323
{
2424
RequiredTypes = requiredTypes;
25-
ExcludedTypes = excludedTypes != null ? excludedTypes : new Type[0];
25+
ExcludedTypes = excludedTypes ?? (new Type[0]);
2626
}
2727

2828
public Type[] RequiredTypes { get; private set; }

Assets/MRTK/Core/Definitions/BoundarySystem/InscribedRectangle.cs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ public class InscribedRectangle
2727
/// <summary>
2828
/// Angles to use for fitting the rectangle within the boundary.
2929
/// </summary>
30-
private static readonly float[] fitAngles = { 0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165 };
30+
private static readonly float[] FitAngles = { 0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165 };
3131

3232
/// <summary>
3333
/// Aspect ratios used when fitting rectangles within the boundary.
3434
/// </summary>
35-
private static float[] aspectRatios = {
35+
private static readonly float[] AspectRatios = {
3636
1.0f, 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 4.5f,
3737
5.0f, 5.5f, 6, 6.5f, 7, 7.5f, 8.0f, 8.5f, 9.0f,
3838
9.5f, 10.0f, 10.5f, 11.0f, 11.5f, 12.0f, 12.5f,
@@ -80,8 +80,7 @@ public class InscribedRectangle
8080
/// <param name="geometryEdges">The boundary geometry.</param>
8181
/// <param name="randomSeed">Random number generator seed.</param>
8282
/// <remarks>
83-
/// For the most reproducible results, use the same randomSeed value
84-
/// each time this method is called.
83+
/// For the most reproducible results, use the same randomSeed value each time this method is called.
8584
/// </remarks>
8685
public InscribedRectangle(Edge[] geometryEdges, int randomSeed)
8786
{
@@ -148,7 +147,7 @@ public InscribedRectangle(Edge[] geometryEdges, int randomSeed)
148147
}
149148
}
150149

151-
for (int angleIndex = 0; angleIndex < fitAngles.Length; angleIndex++)
150+
for (int angleIndex = 0; angleIndex < FitAngles.Length; angleIndex++)
152151
{
153152
for (int pointIndex = 0; pointIndex < startingPoints.Length; pointIndex++)
154153
{
@@ -157,7 +156,7 @@ public InscribedRectangle(Edge[] geometryEdges, int randomSeed)
157156
Vector2 leftCollisionPoint;
158157
Vector2 rightCollisionPoint;
159158

160-
float angleRadians = MathUtilities.DegreesToRadians(fitAngles[angleIndex]);
159+
float angleRadians = MathUtilities.DegreesToRadians(FitAngles[angleIndex]);
161160

162161
// Find the collision point of a cross through the given point at the given angle.
163162
// Note, we are ignoring the return value as we are checking each point's validity
@@ -192,7 +191,7 @@ public InscribedRectangle(Edge[] geometryEdges, int randomSeed)
192191
out newHeight))
193192
{
194193
Center = verticalMidpoint;
195-
Angle = fitAngles[angleIndex];
194+
Angle = FitAngles[angleIndex];
196195
Width = newWidth;
197196
Height = newHeight;
198197
}
@@ -216,7 +215,7 @@ public InscribedRectangle(Edge[] geometryEdges, int randomSeed)
216215
out newHeight))
217216
{
218217
Center = horizontalMidpoint;
219-
Angle = fitAngles[angleIndex];
218+
Angle = FitAngles[angleIndex];
220219
Width = newWidth;
221220
Height = newHeight;
222221
}
@@ -510,19 +509,19 @@ private bool TryFixMaximumRectangle(
510509

511510
// For each aspect ratio we do a binary search to find the maximum rectangle that fits,
512511
// though once we start increasing our area by minimumHeightGain we call it good enough.
513-
for (int i = 0; i < aspectRatios.Length; i++)
512+
for (int i = 0; i < AspectRatios.Length; i++)
514513
{
515514
// The height is limited by the width. If a height would make our width exceed maxWidth, it can't be used
516-
float searchHeightUpperBound = Mathf.Max(maxHeight, maxWidth / aspectRatios[i]);
515+
float searchHeightUpperBound = Mathf.Max(maxHeight, maxWidth / AspectRatios[i]);
517516

518517
// Set to the min height that will out perform our previous area at the given aspect ratio. This is 0 the first time.
519518
// Derived from biggestAreaSoFar=height*(height*aspectRatio)
520-
float searchHeightLowerBound = Mathf.Sqrt(Mathf.Max((width * height), minArea) / aspectRatios[i]);
519+
float searchHeightLowerBound = Mathf.Sqrt(Mathf.Max((width * height), minArea) / AspectRatios[i]);
521520

522521
// If the lowest value needed to outperform the previous best is greater than our max,
523522
// this aspect ratio can't outperform what we've already calculated.
524523
if ((searchHeightLowerBound > searchHeightUpperBound) ||
525-
(searchHeightLowerBound * aspectRatios[i] > maxWidth))
524+
(searchHeightLowerBound * AspectRatios[i] > maxWidth))
526525
{
527526
continue;
528527
}
@@ -536,16 +535,16 @@ private bool TryFixMaximumRectangle(
536535
if (CheckRectangleFit(geometryEdges,
537536
centerPoint,
538537
angleRadians,
539-
aspectRatios[i] * currentTestingHeight,
538+
AspectRatios[i] * currentTestingHeight,
540539
currentTestingHeight))
541540
{
542541
// Binary search up-ward
543542
// If the rectangle will fit, increase the lower bounds of our binary search
544543
searchHeightLowerBound = currentTestingHeight;
545544

546-
width = currentTestingHeight * aspectRatios[i];
545+
width = currentTestingHeight * AspectRatios[i];
547546
height = currentTestingHeight;
548-
aspectRatio = aspectRatios[i];
547+
aspectRatio = AspectRatios[i];
549548
currentTestingHeight = (searchHeightUpperBound + currentTestingHeight) * 0.5f;
550549
}
551550
else

Assets/MRTK/Core/Definitions/BoundarySystem/MixedRealityBoundaryVisualizationProfile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Microsoft.MixedReality.Toolkit.Boundary
1212
/// </summary>
1313
[CreateAssetMenu(menuName = "Mixed Reality Toolkit/Profiles/Mixed Reality Boundary Visualization Profile", fileName = "MixedRealityBoundaryVisualizationProfile", order = (int)CreateProfileMenuItemIndices.BoundaryVisualization)]
1414
[MixedRealityServiceProfile(typeof(IMixedRealityBoundarySystem))]
15-
[HelpURL("https://microsoft.github.io/MixedRealityToolkit-Unity/Documentation/Boundary/BoundarySystemGettingStarted.html")]
15+
[HelpURL("https://docs.microsoft.com/windows/mixed-reality/mrtk-unity/features/boundary/boundary-system-getting-started")]
1616
public class MixedRealityBoundaryVisualizationProfile : BaseMixedRealityProfile
1717
{
1818
[SerializeField]

Assets/MRTK/Core/Definitions/CameraSystem/MixedRealityCameraProfile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace Microsoft.MixedReality.Toolkit
1616
/// </summary>
1717
[CreateAssetMenu(menuName = "Mixed Reality Toolkit/Profiles/Mixed Reality Camera Profile", fileName = "MixedRealityCameraProfile", order = (int)CreateProfileMenuItemIndices.Camera)]
1818
[MixedRealityServiceProfile(typeof(IMixedRealityCameraSystem))]
19-
[HelpURL("https://microsoft.github.io/MixedRealityToolkit-Unity/Documentation/MixedRealityConfigurationGuide.html#camera")]
19+
[HelpURL("https://docs.microsoft.com/windows/mixed-reality/mrtk-unity/configuration/mixed-reality-configuration-guide#camera")]
2020
public class MixedRealityCameraProfile : BaseMixedRealityProfile
2121
{
2222
[SerializeField]

Assets/MRTK/Core/Providers/Hands/ArticulatedHandDefinition.cs renamed to Assets/MRTK/Core/Definitions/Devices/ArticulatedHandDefinition.cs

Lines changed: 132 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,22 @@ namespace Microsoft.MixedReality.Toolkit.Input
1111
/// <summary>
1212
/// Defines the interactions and data that an articulated hand can provide.
1313
/// </summary>
14-
public class ArticulatedHandDefinition
14+
public class ArticulatedHandDefinition : BaseInputSourceDefinition
1515
{
16-
public ArticulatedHandDefinition(IMixedRealityInputSource source, Handedness handedness)
16+
/// <summary>
17+
/// Constructor.
18+
/// </summary>
19+
/// <param name="source">The input source backing this definition instance. Used for raising events.</param>
20+
/// <param name="handedness">The handedness that this definition instance represents.</param>
21+
public ArticulatedHandDefinition(IMixedRealityInputSource source, Handedness handedness) : base(handedness)
1722
{
18-
inputSource = source;
19-
this.handedness = handedness;
23+
InputSource = source;
2024
}
2125

22-
protected readonly IMixedRealityInputSource inputSource;
23-
protected readonly Handedness handedness;
26+
/// <summary>
27+
/// The input source backing this definition instance.
28+
/// </summary>
29+
protected IMixedRealityInputSource InputSource { get; }
2430

2531
private readonly float cursorBeamBackwardTolerance = 0.5f;
2632
private readonly float cursorBeamUpTolerance = 0.8f;
@@ -86,13 +92,32 @@ public float ExitPinchDistance
8692
/// The articulated hands default interactions.
8793
/// </summary>
8894
/// <remarks>A single interaction mapping works for both left and right articulated hands.</remarks>
89-
public MixedRealityInteractionMapping[] DefaultInteractions => new[]
95+
[System.Obsolete("Call GetDefaultMappings(Handedness) instead.")]
96+
public MixedRealityInteractionMapping[] DefaultInteractions
9097
{
91-
new MixedRealityInteractionMapping(0, "Spatial Pointer", AxisType.SixDof, DeviceInputType.SpatialPointer),
92-
new MixedRealityInteractionMapping(1, "Spatial Grip", AxisType.SixDof, DeviceInputType.SpatialGrip),
93-
new MixedRealityInteractionMapping(2, "Select", AxisType.Digital, DeviceInputType.Select),
94-
new MixedRealityInteractionMapping(3, "Grab", AxisType.SingleAxis, DeviceInputType.TriggerPress),
95-
new MixedRealityInteractionMapping(4, "Index Finger Pose", AxisType.SixDof, DeviceInputType.IndexFinger)
98+
get
99+
{
100+
MixedRealityInteractionMapping[] defaultInteractions = new MixedRealityInteractionMapping[DefaultMappings.Length];
101+
for (int i = 0; i < DefaultMappings.Length; i++)
102+
{
103+
defaultInteractions[i] = new MixedRealityInteractionMapping((uint)i, DefaultMappings[i]);
104+
}
105+
return defaultInteractions;
106+
}
107+
}
108+
109+
/// <summary>
110+
/// The articulated hands default interactions.
111+
/// </summary>
112+
/// <remarks>A single interaction mapping works for both left and right articulated hands.</remarks>
113+
protected override MixedRealityInputActionMapping[] DefaultMappings => new[]
114+
{
115+
new MixedRealityInputActionMapping("Spatial Pointer", AxisType.SixDof, DeviceInputType.SpatialPointer),
116+
new MixedRealityInputActionMapping("Spatial Grip", AxisType.SixDof, DeviceInputType.SpatialGrip),
117+
new MixedRealityInputActionMapping("Select", AxisType.Digital, DeviceInputType.Select),
118+
new MixedRealityInputActionMapping("Grab", AxisType.SingleAxis, DeviceInputType.TriggerPress),
119+
new MixedRealityInputActionMapping("Index Finger Pose", AxisType.SixDof, DeviceInputType.IndexFinger),
120+
new MixedRealityInputActionMapping("Teleport Pose", AxisType.DualAxis, DeviceInputType.ThumbStick),
96121
};
97122

98123
/// <summary>
@@ -122,11 +147,34 @@ public bool IsInPointingPose
122147
}
123148
}
124149
}
125-
return true;
150+
return !IsInTeleportPose;
126151
}
127152
}
128153

129-
private static readonly ProfilerMarker UpdateHandJointsPerfMarker = new ProfilerMarker("[MRTK] ArticulatedHandDefinition.UpdateHandJoints");
154+
/// <summary>
155+
/// Calculates whether the current pose is the one to start a teleport action
156+
/// </summary>
157+
protected bool IsInTeleportPose
158+
{
159+
get
160+
{
161+
if (!unityJointPoses.TryGetValue(TrackedHandJoint.Palm, out var palmPose)) return false;
162+
163+
Camera mainCamera = CameraCache.Main;
164+
165+
if (mainCamera == null)
166+
{
167+
return false;
168+
}
169+
170+
Transform cameraTransform = mainCamera.transform;
171+
172+
// We check if the palm up is roughly in line with the camera up
173+
return Vector3.Dot(-palmPose.Up, cameraTransform.up) > 0.6f
174+
// Thumb must be extended, and middle must be grabbing
175+
&& !isThumbGrabbing && isMiddleGrabbing;
176+
}
177+
}
130178

131179
/// <summary>
132180
/// Calculates whether the current the current joint pose is selecting (air tap gesture).
@@ -159,6 +207,12 @@ public bool IsPinching
159207
}
160208
}
161209

210+
private bool isIndexGrabbing;
211+
private bool isMiddleGrabbing;
212+
private bool isThumbGrabbing;
213+
214+
private static readonly ProfilerMarker UpdateHandJointsPerfMarker = new ProfilerMarker("[MRTK] ArticulatedHandDefinition.UpdateHandJoints");
215+
162216
/// <summary>
163217
/// Updates the current hand joints with new data.
164218
/// </summary>
@@ -168,7 +222,7 @@ public void UpdateHandJoints(Dictionary<TrackedHandJoint, MixedRealityPose> join
168222
using (UpdateHandJointsPerfMarker.Auto())
169223
{
170224
unityJointPoses = jointPoses;
171-
CoreServices.InputSystem?.RaiseHandJointsUpdated(inputSource, handedness, unityJointPoses);
225+
CoreServices.InputSystem?.RaiseHandJointsUpdated(InputSource, Handedness, unityJointPoses);
172226
}
173227
}
174228

@@ -191,10 +245,72 @@ public void UpdateCurrentIndexPose(MixedRealityInteractionMapping interactionMap
191245
if (interactionMapping.Changed)
192246
{
193247
// Raise input system event if it's enabled
194-
CoreServices.InputSystem?.RaisePoseInputChanged(inputSource, handedness, interactionMapping.MixedRealityInputAction, currentIndexPose);
248+
CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, Handedness, interactionMapping.MixedRealityInputAction, currentIndexPose);
195249
}
196250
}
197251
}
198252
}
253+
254+
// Used to track the input that was last raised
255+
private bool previousReadyToTeleport = false;
256+
257+
private IMixedRealityTeleportPointer teleportPointer;
258+
259+
private static readonly ProfilerMarker UpdateCurrentTeleportPosePerfMarker = new ProfilerMarker("[MRTK] ArticulatedHandDefinition.UpdateCurrentTeleportPose");
260+
261+
public void UpdateCurrentTeleportPose(MixedRealityInteractionMapping interactionMapping)
262+
{
263+
using (UpdateCurrentTeleportPosePerfMarker.Auto())
264+
{
265+
// Check if we're focus locked or near something interactive to avoid teleporting unintentionally.
266+
bool anyPointersLockedWithHand = false;
267+
for (int i = 0; i < InputSource?.Pointers?.Length; i++)
268+
{
269+
IMixedRealityPointer mixedRealityPointer = InputSource.Pointers[i];
270+
if (mixedRealityPointer.IsNull()) continue;
271+
if (mixedRealityPointer is IMixedRealityNearPointer nearPointer)
272+
{
273+
anyPointersLockedWithHand |= nearPointer.IsNearObject;
274+
}
275+
anyPointersLockedWithHand |= mixedRealityPointer.IsFocusLocked;
276+
277+
// If official teleport mode and we have a teleport pointer registered, we get the input action to trigger it.
278+
if (teleportPointer == null && mixedRealityPointer is IMixedRealityTeleportPointer pointer)
279+
{
280+
teleportPointer = pointer;
281+
}
282+
}
283+
284+
// We close middle finger to signal spider-man gesture, and as being ready for teleport
285+
isIndexGrabbing = HandPoseUtils.IsIndexGrabbing(Handedness);
286+
isMiddleGrabbing = HandPoseUtils.IsMiddleGrabbing(Handedness);
287+
isThumbGrabbing = HandPoseUtils.IsThumbGrabbing(Handedness);
288+
bool isReadyForTeleport = !anyPointersLockedWithHand && IsInTeleportPose;
289+
290+
// Tracks the input vector that should be sent out based on the gesture that is made
291+
Vector2 stickInput = (isReadyForTeleport && !isIndexGrabbing) ? Vector2.up : Vector2.zero;
292+
293+
// The teleport event needs to be canceled if we have not completed the teleport motion and we were previously ready to teleport, but for some reason we
294+
// are no longer doing the ready to teleport gesture
295+
bool teleportCanceled = previousReadyToTeleport && !isReadyForTeleport && !isIndexGrabbing;
296+
if (teleportCanceled && teleportPointer != null)
297+
{
298+
CoreServices.TeleportSystem?.RaiseTeleportCanceled(teleportPointer, null);
299+
previousReadyToTeleport = isReadyForTeleport;
300+
return;
301+
}
302+
303+
// Update the interaction data source
304+
interactionMapping.Vector2Data = stickInput;
305+
306+
// If our value changed raise it
307+
if (interactionMapping.Changed)
308+
{
309+
CoreServices.InputSystem?.RaisePositionInputChanged(InputSource, Handedness, interactionMapping.MixedRealityInputAction, stickInput);
310+
}
311+
312+
previousReadyToTeleport = isReadyForTeleport;
313+
}
314+
}
199315
}
200316
}

Assets/MRTK/Core/Providers/Hands/ArticulatedHandDefinition.cs.meta renamed to Assets/MRTK/Core/Definitions/Devices/ArticulatedHandDefinition.cs.meta

File renamed without changes.

0 commit comments

Comments
 (0)