/// <summary> /// Attempts to load the glTF controller model from the Windows SDK. /// </summary> /// <returns>The controller model as a GameObject or null if it was unobtainable.</returns> public async Task <GameObject> TryGenerateControllerModelFromPlatformSDK() { if (spatialInteractionSource == null) { return(null); } // See if we've generated this model before and if we can return it if (ControllerModelDictionary.TryGetValue(GenerateKey(spatialInteractionSource), out GameObject controllerModel)) { controllerModel.SetActive(true); return(controllerModel); } Debug.Log("Trying to load controller model from platform SDK"); byte[] fileBytes = null; var controllerModelStream = await spatialInteractionSource.Controller.TryGetRenderableModelAsync(); if (controllerModelStream == null || controllerModelStream.Size == 0) { Debug.LogError("Failed to obtain controller model from driver"); } else { fileBytes = new byte[controllerModelStream.Size]; using (DataReader reader = new DataReader(controllerModelStream)) { await reader.LoadAsync((uint)controllerModelStream.Size); reader.ReadBytes(fileBytes); } } GameObject gltfGameObject = null; if (fileBytes != null) { Utilities.Gltf.Schema.GltfObject gltfObject = GltfUtility.GetGltfObjectFromGlb(fileBytes); gltfGameObject = await gltfObject.ConstructAsync(); if (gltfGameObject != null) { ControllerModelDictionary.Add(GenerateKey(spatialInteractionSource), gltfGameObject); } } return(gltfGameObject); }
// Disables "This async method lacks 'await' operators and will run synchronously." when the correct OpenXR package isn't installed #pragma warning disable CS1998 /// <summary> /// Attempts to load the glTF controller model from OpenXR. /// </summary> /// <returns>The controller model as a GameObject or null if it was unobtainable.</returns> public async Task <GameObject> TryGenerateControllerModelFromPlatformSDK() { GameObject gltfGameObject = null; #if MSFT_OPENXR && (UNITY_STANDALONE_WIN || UNITY_WSA || UNITY_ANDROID) if (!controllerModelProvider.TryGetControllerModelKey(out ulong modelKey)) { Debug.LogError("Failed to obtain controller model key from platform."); return(null); } if (ControllerModelDictionary.TryGetValue(modelKey, out gltfGameObject)) { gltfGameObject.SetActive(true); return(gltfGameObject); } byte[] modelStream = await controllerModelProvider.TryGetControllerModel(modelKey); if (modelStream == null || modelStream.Length == 0) { Debug.LogError("Failed to obtain controller model from platform."); return(null); } Utilities.Gltf.Schema.GltfObject gltfObject = GltfUtility.GetGltfObjectFromGlb(modelStream); gltfGameObject = await gltfObject.ConstructAsync(); if (gltfGameObject != null) { // After all the awaits, double check that another task didn't finish earlier if (ControllerModelDictionary.TryGetValue(modelKey, out GameObject existingGameObject)) { Object.Destroy(gltfGameObject); return(existingGameObject); } else { ControllerModelDictionary.Add(modelKey, gltfGameObject); } } #endif // MSFT_OPENXR && (UNITY_STANDALONE_WIN || UNITY_WSA || UNITY_ANDROID) return(gltfGameObject); }
/// <summary> /// Method <c>LoadHologram</c> is used to load hologram from Storage server /// It requires thehologram ID as the parameter /// </summary> /// <param name="hologramID">ID of Hologram</param> public static async void LoadHologram(string hologramID, HologramInstantiationSettings setting = null) { if (setting == null) { setting = new HologramInstantiationSettings(); } string getHologramUri = $"{BaseUri}/holograms/{hologramID}/download"; Response response = new Response(); try { response = await Rest.GetAsync(getHologramUri); } catch (Exception e) { Debug.LogError(e.Message); } if (!response.Successful) { Debug.LogError($"Failed to get glb model from {getHologramUri}"); return; } var gltfObject = GltfUtility.GetGltfObjectFromGlb(response.ResponseData); try { GameObject loadedObject = await gltfObject.ConstructAsync(); HologramInstantiationSettings.Initialize(loadedObject, setting); } catch (Exception e) { Debug.LogError($"{e.Message}\n{e.StackTrace}"); return; } }
private async void Start() { Response response = new Response(); try { response = await Rest.GetAsync(uri); } catch (Exception e) { Debug.LogError(e.Message); } if (!response.Successful) { Debug.LogError($"Failed to get glb model from {uri}"); return; } var gltfObject = GltfUtility.GetGltfObjectFromGlb(response.ResponseData); try { await gltfObject.ConstructAsync(); } catch (Exception e) { Debug.LogError($"{e.Message}\n{e.StackTrace}"); return; } if (gltfObject != null) { Debug.Log("Import successful"); } }
private async void CreateControllerModelFromPlatformSDK(uint interactionSourceId) { Debug.Log("Creating controller model from platform SDK"); byte[] fileBytes = null; #if WINDOWS_UWP var controllerModelStream = await TryGetRenderableModelAsync(interactionSourceId); if (controllerModelStream == null || controllerModelStream.Size == 0) { Debug.LogError("Failed to obtain controller model from driver"); } else { fileBytes = new byte[controllerModelStream.Size]; using (DataReader reader = new DataReader(controllerModelStream)) { await reader.LoadAsync((uint)controllerModelStream.Size); reader.ReadBytes(fileBytes); } } #endif GameObject gltfGameObject = null; if (fileBytes != null) { var gltfObject = GltfUtility.GetGltfObjectFromGlb(fileBytes); gltfGameObject = await gltfObject.ConstructAsync(); if (gltfGameObject != null) { var visualizationProfile = GetControllerVisualizationProfile(); if (visualizationProfile != null) { var visualizationType = visualizationProfile.GetControllerVisualizationTypeOverride(GetType(), ControllerHandedness); if (visualizationType != null) { gltfGameObject.AddComponent(visualizationType.Type); TryAddControllerModelToSceneHierarchy(gltfGameObject); } else { Debug.LogError("Controller visualization type not defined for controller visualization profile"); GameObject.Destroy(gltfGameObject); gltfGameObject = null; } } else { Debug.LogError("Failed to obtain a controller visualization profile"); } } } failedToObtainControllerModel = (gltfGameObject == null); if (failedToObtainControllerModel) { Debug.LogWarning("Failed to create controller model from driver, defaulting to BaseController behavior"); TryRenderControllerModel(GetType(), InputSourceType.Controller); } }
private async void CreateControllerModelFromPlatformSDK(InteractionSource interactionSource) { Debug.Log("Trying to load controller model from platform SDK"); byte[] fileBytes = null; #if WINDOWS_UWP var controllerModelStream = await interactionSource.TryGetRenderableModelAsync(); if (controllerModelStream == null || controllerModelStream.Size == 0) { Debug.LogError("Failed to obtain controller model from driver"); } else { fileBytes = new byte[controllerModelStream.Size]; using (DataReader reader = new DataReader(controllerModelStream)) { await reader.LoadAsync((uint)controllerModelStream.Size); reader.ReadBytes(fileBytes); } } #endif GameObject gltfGameObject = null; if (fileBytes != null) { var gltfObject = GltfUtility.GetGltfObjectFromGlb(fileBytes); gltfGameObject = await gltfObject.ConstructAsync(); if (gltfGameObject != null) { var visualizationProfile = GetControllerVisualizationProfile(); if (visualizationProfile != null) { var visualizationType = visualizationProfile.GetControllerVisualizationTypeOverride(GetType(), ControllerHandedness); if (visualizationType != null) { // Set the platform controller model to not be destroyed when the source is lost. It'll be disabled instead, // and re-enabled when the same controller is re-detected. if (gltfGameObject.AddComponent(visualizationType.Type) is IMixedRealityControllerPoseSynchronizer visualizer) { visualizer.DestroyOnSourceLost = false; } TryAddControllerModelToSceneHierarchy(gltfGameObject); controllerDictionary.Add(GenerateKey(interactionSource), gltfGameObject); } else { Debug.LogError("Controller visualization type not defined for controller visualization profile"); UnityEngine.Object.Destroy(gltfGameObject); gltfGameObject = null; } } else { Debug.LogError("Failed to obtain a controller visualization profile"); } } } failedToObtainControllerModel = (gltfGameObject == null); if (failedToObtainControllerModel) { Debug.LogWarning("Failed to create controller model from driver, defaulting to BaseController behavior"); TryRenderControllerModel(GetType(), InputSourceType.Controller); } }
/// <summary> /// Attempts to load the controller model render settings from the <see cref="MixedRealityControllerVisualizationProfile"/> /// to render the controllers in the scene. /// </summary> /// <param name="controllerType">The controller type.</param> /// <param name="glbData">The raw binary glb data of the controller model, typically loaded from the driver.</param> /// <param name="useAlternatePoseAction">Should the visualizer be assigned the alternate pose actions?</param> /// <returns>True, if controller model is being properly rendered.</returns> internal async Task TryRenderControllerModelAsync(Type controllerType, byte[] glbData = null, bool useAlternatePoseAction = false) { var visualizationProfile = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.ControllerVisualizationProfile; if (visualizationProfile == null) { Debug.LogError("Missing ControllerVisualizationProfile!"); return; } if (!visualizationProfile.RenderMotionControllers) { return; } GameObject controllerModel = null; // If a specific controller template wants to override the global model, assign that instead. if (!visualizationProfile.UseDefaultModels) { controllerModel = visualizationProfile.GetControllerModelOverride(controllerType, ControllerHandedness); } // Attempt to load the controller model from glbData. if (controllerModel == null && glbData != null) { var gltfObject = GltfUtility.GetGltfObjectFromGlb(glbData); await gltfObject.ConstructAsync(); controllerModel = gltfObject.GameObjectReference; controllerModel.name = $"{controllerType.Name}_Visualization"; controllerModel.transform.SetParent(MixedRealityToolkit.Instance.MixedRealityPlayspace.transform); var visualizationType = visualizationProfile.GetControllerVisualizationTypeOverride(controllerType, ControllerHandedness) ?? visualizationProfile.ControllerVisualizationType; controllerModel.AddComponent(visualizationType.Type); Visualizer = controllerModel.GetComponent <IMixedRealityControllerVisualizer>(); if (Visualizer != null) { Visualizer.Controller = this; SetupController(Visualizer); return; // Nothing left to do; } Debug.LogWarning($"Failed to attach a valid IMixedRealityControllerVisualizer to {controllerModel.name}"); } // If we didn't get an override model, and we didn't load the driver model, // then get the global controller model for each hand. if (controllerModel == null) { switch (ControllerHandedness) { case Handedness.Left when visualizationProfile.GlobalLeftHandModel != null: controllerModel = visualizationProfile.GlobalLeftHandModel; break; case Handedness.Right when visualizationProfile.GlobalRightHandModel != null: controllerModel = visualizationProfile.GlobalRightHandModel; break; } } // If we've got a controller model prefab, then place it in the scene. if (controllerModel != null) { var controllerObject = UnityEngine.Object.Instantiate(controllerModel, MixedRealityToolkit.Instance.MixedRealityPlayspace); controllerObject.name = $"{controllerType.Name}_{controllerObject.name}"; Visualizer = controllerObject.GetComponent <IMixedRealityControllerVisualizer>(); if (Visualizer != null) { Visualizer.Controller = this; SetupController(Visualizer); } else { Debug.LogError($"{controllerObject.name} is missing a IMixedRealityControllerVisualizer component!"); } } if (Visualizer == null) { Debug.LogError("Failed to render controller model!"); } void SetupController(IMixedRealityControllerVisualizer visualizer) { if (!useAlternatePoseAction && visualizationProfile.TryGetControllerPose(controllerType, ControllerHandedness, out MixedRealityInputAction poseAction)) { visualizer.UseSourcePoseData = false; visualizer.PoseAction = poseAction; } else if (useAlternatePoseAction && visualizationProfile.TryGetControllerPoseOverride(controllerType, ControllerHandedness, out MixedRealityInputAction altPoseAction)) { visualizer.UseSourcePoseData = false; visualizer.PoseAction = altPoseAction; } else { Debug.LogError("Failed to get pose actions for controller visual."); } } }
/// <summary> /// Attempts to load the controller model render settings from the <see cref="MixedRealityControllerVisualizationProfile"/> /// to render the controllers in the scene. /// </summary> /// <param name="controllerType">The controller type.</param> /// <param name="glbData">The raw binary glb data of the controller model, typically loaded from the driver.</param> /// <param name="useAlternatePoseAction">Should the visualizer be assigned the alternate pose actions?</param> /// <returns>True, if controller model is being properly rendered.</returns> /// <remarks> /// (Given a user can, have no system default and override specific controller types with a system default, OR, enable a system system default but override that default for specific controllers) /// Flow is as follows: /// 1. Check if either there is a global setting for an system override and if there is a specific customization for that controller type /// 2. If either the there is a system data and either the /// /// </remarks> internal async Task TryRenderControllerModelAsync(Type controllerType, byte[] glbData = null, bool useAlternatePoseAction = false) { if (controllerType == null) { Debug.LogError("Unknown type of controller, cannot render"); return; } var visualizationProfile = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.ControllerVisualizationProfile; if (visualizationProfile == null) { Debug.LogError("Missing ControllerVisualizationProfile!"); return; } if (!visualizationProfile.RenderMotionControllers) { return; } GltfObject gltfObject = null; // If a specific controller template exists, check if it wants to override the global model, or use the system default specifically (in case global default is not used) bool useSystemDefaultModels = visualizationProfile.GetControllerModelOverride(controllerType, ControllerHandedness, out var controllerModel); // If an override is not configured for defaults and has no model, then use the system default check if (!useSystemDefaultModels && controllerModel == null) { useSystemDefaultModels = visualizationProfile.UseDefaultModels; } // if we have model data from the platform and the controller has been configured to use the default model, attempt to load the controller model from glbData. if (glbData != null && useSystemDefaultModels) { gltfObject = GltfUtility.GetGltfObjectFromGlb(glbData); await gltfObject.ConstructAsync(); controllerModel = gltfObject.GameObjectReference; } // If we didn't get an override model, and we didn't load the driver model, // then get the global controller model for each hand. if (controllerModel == null) { switch (ControllerHandedness) { case Handedness.Left when visualizationProfile.GlobalLeftHandModel != null: controllerModel = visualizationProfile.GlobalLeftHandModel; break; case Handedness.Right when visualizationProfile.GlobalRightHandModel != null: controllerModel = visualizationProfile.GlobalRightHandModel; break; } } // If we've got a controller model, then place it in the scene and get/attach the visualizer. if (controllerModel != null) { //If the model was loaded from a system template if (useSystemDefaultModels && gltfObject != null) { controllerModel.name = $"{controllerType.Name}_Visualization"; controllerModel.transform.SetParent(MixedRealityToolkit.CameraSystem?.CameraRig.PlayspaceTransform); var visualizationType = visualizationProfile.GetControllerVisualizationTypeOverride(controllerType, ControllerHandedness) ?? visualizationProfile.ControllerVisualizationType; controllerModel.AddComponent(visualizationType.Type); Visualizer = controllerModel.GetComponent <IMixedRealityControllerVisualizer>(); } //If the model was a prefab else { var controllerObject = UnityEngine.Object.Instantiate(controllerModel, MixedRealityToolkit.CameraSystem?.CameraRig.PlayspaceTransform); controllerObject.name = $"{controllerType.Name}_Visualization"; Visualizer = controllerObject.GetComponent <IMixedRealityControllerVisualizer>(); } //If a visualizer exists, set it up and bind it to the controller if (Visualizer != null) { Visualizer.Controller = this; SetupController(Visualizer); } else { Debug.LogWarning($"Failed to attach a valid IMixedRealityControllerVisualizer to {controllerType.Name}"); } } if (Visualizer == null) { Debug.LogError("Failed to render controller model!"); } void SetupController(IMixedRealityControllerVisualizer visualizer) { if (!useAlternatePoseAction && visualizationProfile.TryGetControllerPose(controllerType, ControllerHandedness, out MixedRealityInputAction poseAction)) { visualizer.UseSourcePoseData = false; visualizer.PoseAction = poseAction; } else if (useAlternatePoseAction && visualizationProfile.TryGetControllerPoseOverride(controllerType, ControllerHandedness, out MixedRealityInputAction altPoseAction)) { visualizer.UseSourcePoseData = false; visualizer.PoseAction = altPoseAction; } else if (visualizationProfile.GlobalPointerPose != MixedRealityInputAction.None) { visualizer.UseSourcePoseData = false; visualizer.PoseAction = visualizationProfile.GlobalPointerPose; } else { Debug.LogError("Failed to get pose actions for controller visual."); } } }
// Disables "This async method lacks 'await' operators and will run synchronously." for non-UWP #pragma warning disable CS1998 /// <summary> /// Attempts to load the glTF controller model from the Windows SDK. /// </summary> /// <returns>The controller model as a GameObject or null if it was unobtainable.</returns> public async Task <GameObject> TryGenerateControllerModelFromPlatformSDK() { GameObject gltfGameObject = null; #if WINDOWS_UWP if (spatialInteractionSource == null) { return(null); } string key = GenerateKey(spatialInteractionSource); // See if we've generated this model before and if we can return it if (ControllerModelDictionary.TryGetValue(key, out gltfGameObject)) { gltfGameObject.SetActive(true); return(gltfGameObject); } Debug.Log("Trying to load controller model from platform SDK"); byte[] fileBytes = null; var controllerModelStream = await spatialInteractionSource.Controller.TryGetRenderableModelAsync(); if (controllerModelStream == null || controllerModelStream.Size == 0) { Debug.LogError("Failed to obtain controller model from driver"); } else { fileBytes = new byte[controllerModelStream.Size]; using (DataReader reader = new DataReader(controllerModelStream)) { await reader.LoadAsync((uint)controllerModelStream.Size); reader.ReadBytes(fileBytes); } } if (fileBytes != null) { Utilities.Gltf.Schema.GltfObject gltfObject = GltfUtility.GetGltfObjectFromGlb(fileBytes); gltfGameObject = await gltfObject.ConstructAsync(); if (gltfGameObject != null) { // After all the awaits, double check that another task didn't finish earlier if (ControllerModelDictionary.TryGetValue(key, out GameObject existingGameObject)) { UnityEngine.Object.Destroy(gltfGameObject); return(existingGameObject); } else { ControllerModelDictionary.Add(key, gltfGameObject); } } } #endif // WINDOWS_UWP return(gltfGameObject); }
/// <summary> /// Attempts to load the controller model render settings from the <see cref="MixedRealityControllerVisualizationProfile"/> /// to render the controllers in the scene. /// </summary> /// <param name="glbData">The raw binary glb data of the controller model, typically loaded from the driver.</param> /// <param name="useAlternatePoseAction">Should the visualizer be assigned the alternate pose actions?</param> public async Task TryRenderControllerModelAsync(byte[] glbData = null, bool useAlternatePoseAction = false) { if (visualizationProfile.IsNull()) { Debug.LogWarning($"Missing {nameof(visualizationProfile)} for {GetType().Name}"); return; } GltfObject gltfObject = null; GameObject controllerModel = null; // if we have model data from the platform and the controller has been configured to use the default model, attempt to load the controller model from glbData. if (glbData != null) { gltfObject = GltfUtility.GetGltfObjectFromGlb(glbData); await gltfObject.ConstructAsync(); controllerModel = gltfObject.GameObjectReference; } // If we didn't get an override model, and we didn't load the driver model, // then get the global controller model for each hand. if (controllerModel.IsNull()) { switch (ControllerHandedness) { case Handedness.Left when !visualizationProfile.LeftHandModel.IsNull(): controllerModel = visualizationProfile.LeftHandModel; break; case Handedness.Right when !visualizationProfile.LeftHandModel.IsNull(): controllerModel = visualizationProfile.LeftHandModel; break; } } // If we've got a controller model, then place it in the scene and get/attach the visualizer. if (!controllerModel.IsNull()) { var playspaceTransform = MixedRealityToolkit.CameraSystem != null ? MixedRealityToolkit.CameraSystem.MainCameraRig.PlayspaceTransform : CameraCache.Main.transform.parent; // If the model was loaded from a system template if (gltfObject != null) { controllerModel.name = $"{GetType().Name}_Visualization"; controllerModel.transform.SetParent(playspaceTransform); var visualizationType = visualizationProfile.ControllerVisualizationType; controllerModel.AddComponent(visualizationType.Type); Visualizer = controllerModel.GetComponent <IMixedRealityControllerVisualizer>(); } // If the model was a prefab else { var controllerObject = Object.Instantiate(controllerModel, playspaceTransform) as GameObject; Debug.Assert(controllerObject != null); controllerObject.name = $"{GetType().Name}_Visualization"; Visualizer = controllerObject.GetComponent <IMixedRealityControllerVisualizer>(); } // If a visualizer exists, set it up and bind it to the controller if (Visualizer != null) { Visualizer.Controller = this; SetupController(Visualizer); } else { Debug.LogWarning($"Failed to attach a valid {nameof(IMixedRealityControllerVisualizer)} to {GetType().Name}"); } } if (Visualizer == null) { Debug.LogError("Failed to render controller model!"); } void SetupController(IMixedRealityControllerVisualizer visualizer) { if (useAlternatePoseAction) { visualizer.UseSourcePoseData = visualizationProfile.AlternatePointerPose == MixedRealityInputAction.None; visualizer.PoseAction = visualizationProfile.AlternatePointerPose; } else { visualizer.UseSourcePoseData = visualizationProfile.PointerPose == MixedRealityInputAction.None; visualizer.PoseAction = visualizationProfile.PointerPose; } } }