Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded OpenXR Layer Support #1348

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from
8 changes: 8 additions & 0 deletions Packages/Tracking/OpenXR/API Layer.meta

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

134 changes: 134 additions & 0 deletions Packages/Tracking/OpenXR/API Layer/HandTrackingApiLayerFeature.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using JetBrains.Annotations;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine.XR.OpenXR;
using UnityEngine.XR.OpenXR.Features;

#if UNITY_EDITOR
using System;
using UnityEditor;
using UnityEditor.XR.OpenXR.Features;
using UnityEditor.Build.Reporting;
using UnityEngine.XR.OpenXR.Features.MetaQuestSupport;
#endif

namespace Leap.Tracking.OpenXR.ApiLayer
{
/// <summary>
/// Embeddable Ultraleap OpenXR API Layer.
/// </summary>
#if UNITY_EDITOR
[OpenXRFeature(FeatureId = FeatureId,
Version = "1.7.2",
UiName = "Ultraleap OpenXR API Layer (Embedded)",
Company = "Ultraleap",
Desc = "Embeddable API layer for Ultraleap Hand Tracking",
Category = FeatureCategory.Feature,
Required = false,
OpenxrExtensionStrings = "",
BuildTargetGroups = new[] { BuildTargetGroup.Android }
)]
#endif
public class HandTrackingApiLayerFeature : OpenXRFeature
{
[PublicAPI] public const string FeatureId = "com.ultraleap.tracking.openxr.feature.handtracking.api_layer";

#if UNITY_EDITOR
protected override void GetValidationChecks(List<ValidationRule> rules, BuildTargetGroup targetGroup)
{
// Attempt to check the version of OpenXR for at least 1.0.25 as a proxy for what loader version is
// included.
rules.Add(new ValidationRule(this)
{
message = "The OpenXR loader must be at least version 1.0.25 to support embedding the Ultraleap API layer",
error = false,
checkPredicate = () => Version.Parse(OpenXRRuntime.apiVersion) >= new Version(1, 0, 25),
fixItAutomatic = false,
});

// Ensure that the Legacy "Meta Quest Support" OpenXR feature is not enabled.
rules.Add(new ValidationRule(this)
{
message = "Embedded layer is not supported with legacy Meta Quest Support OpenXR feature",
error = true,
checkPredicate = () => {
var quest = OpenXRSettings.ActiveBuildTargetInstance.GetFeature<MetaQuestFeature>();
if (quest == null)
return true;
return !quest.enabled; },
fixItAutomatic = true,
fixIt = () => {
var quest = OpenXRSettings.ActiveBuildTargetInstance.GetFeature<MetaQuestFeature>();
if(quest != null)
quest.enabled = false;
},
fixItMessage = "Disabled legacy Meta Quest Support OpenXR feature"
});
}
#endif
}

#if UNITY_EDITOR
public class HandTrackingApiLayerFeatureBuildHooks : OpenXRFeatureBuildHooks
{
public override int callbackOrder => 1;
public override Type featureType => typeof(HandTrackingApiLayerFeature);

protected override void OnPreprocessBuildExt(BuildReport report)
{
}

protected override void OnPostGenerateGradleAndroidProjectExt(string path)
{
// Remove libLeapC.so and AndroidServiceBinder.aar before Gradle is run.
// This is to work-around the fact that they are also included in the embedded API layer and will cause
// conflicts.
RemoveAAR(path, "UltraleapTrackingServiceBinder");
RemoveLibrary(path, "arm64-v8a", "LeapC");
}

protected override void OnPostprocessBuildExt(BuildReport report)
{
}

/// <summary>
/// Removes an AAR from the project and the associated Gradle build script
/// </summary>
/// <param name="path">The project path</param>
/// <param name="aarName">The name of the AAR library without the `.aar` extension</param>
private void RemoveAAR(string path, string aarName)
{
// Delete the AAR from the project before Gradle is run.
var aarPath = Path.Combine(path, "libs", $"{aarName}.aar");
if (File.Exists(aarPath))
{
File.Delete(aarPath);
}

// Remove the reference to the AAR from the Gradle build script.
var buildScriptPath = Path.Combine(path, "build.gradle");
var buildScriptContent = File.ReadAllLines(buildScriptPath);
var modifiedBuildScriptContent = buildScriptContent.Where(
line => !(line.Contains("implementation(") && line.Contains(aarName) && line.Contains("ext:'aar'"))
);
File.WriteAllLines(buildScriptPath, modifiedBuildScriptContent);
}

/// <summary>
/// Removes a .so library from the build
/// </summary>
/// <param name="path">The project path</param>
/// <param name="architecture">The CPU architecture of the library</param>
/// <param name="libName">the library name without the .so or lib prefix</param>
private void RemoveLibrary(string path, string architecture, string libName)
{
var libPath = Path.Combine(path, "src", "main", "jniLibs", architecture, $"lib{libName}.so");
if (File.Exists(libPath))
{
File.Delete(libPath);
}
}
}
#endif
}

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,29 @@
{
"name": "Ultraleap.Tracking.OpenXR.ApiLayer",
"rootNamespace": "Leap.Tracking.OpenXR.ApiLayer",
"references": [
"GUID:4847341ff46394e83bb78fbd0652937e",
"GUID:96aa6ba065960476598f8f643e7252b6",
"GUID:95054a9710b0f114a85f6ced6b7f891c"
],
"includePlatforms": [
"Android",
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [
"XR_OPENXR_ENABLED"
],
"versionDefines": [
{
"name": "com.unity.xr.openxr",
"expression": "1.0",
"define": "XR_OPENXR_ENABLED"
}
],
"noEngineReferences": false
}

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

Binary file not shown.

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

27 changes: 27 additions & 0 deletions Packages/Tracking/OpenXR/Editor/Scripts/UltraleapFeatureSet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using JetBrains.Annotations;
using Leap.Tracking.OpenXR.ApiLayer;
using UnityEditor;
using UnityEditor.XR.OpenXR.Features;

namespace Leap.Tracking.OpenXR
{
[OpenXRFeatureSet(
FeatureIds = new string[]
{
HandTrackingFeature.FeatureId,
HandTrackingApiLayerFeature.FeatureId
},
UiName = "Ultraleap Hand Tracking",
Description = "Ultraleap hand-tracking support",
FeatureSetId = FeatureSetId,
SupportedBuildTargets = new BuildTargetGroup[]
{
BuildTargetGroup.Standalone,
BuildTargetGroup.Android
}
)]
public class UltraleapFeatureSet
{
[PublicAPI] public const string FeatureSetId = "com.ultraleap.tracking.openxr.featureset.handtracking";
}
}

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
@@ -1,6 +1,6 @@
{
"name": "Ultraleap.Tracking.OpenXR.Editor",
"rootNamespace": "Ultraleap.Tracking.OpenXR",
"rootNamespace": "Leap.Tracking.OpenXR",
"references": [
"GUID:4847341ff46394e83bb78fbd0652937e",
"GUID:96aa6ba065960476598f8f643e7252b6",
Expand All @@ -10,7 +10,8 @@
"GUID:343deaaf83e0cee4ca978e7df0b80d21",
"GUID:2bafac87e7f4b9b418d9448d219b01ab",
"GUID:0acc523941302664db1f4e527237feb3",
"GUID:27619889b8ba8c24980f49ee34dbb44a"
"GUID:27619889b8ba8c24980f49ee34dbb44a",
"GUID:e81fa8def7d1fab46902540cb82dd934"
],
"includePlatforms": [
"Editor"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
{
"name": "Ultraleap.Tracking.OpenXR",
"rootNamespace": "Ultraleap.Tracking.OpenXR",
"rootNamespace": "Leap.Tracking.OpenXR",
"references": [
"GUID:4847341ff46394e83bb78fbd0652937e",
"GUID:96aa6ba065960476598f8f643e7252b6",
"GUID:cec9848704c49724192ff47f9b3e9156",
"GUID:2ee0542102ac1084e8d9a910885c1e81",
"GUID:ba171b3dd2a51234ab864770f99741a5",
"GUID:e40ba710768534012815d3193fa296cb"
],
Expand Down