async void LoadModelAsync(string path) { var ext = Path.GetExtension(path).ToLower(); switch (ext) { case ".gltf": case ".glb": case ".zip": { var instance = await GltfUtility.LoadAsync(path, GetIAwaitCaller(m_useAsync.isOn), GetGltfMaterialGenerator(m_useUrpMaterial.isOn)); break; } case ".vrm": { VrmUtility.MaterialGeneratorCallback materialCallback = (VRM.glTF_VRM_extensions vrm) => GetVrmMaterialGenerator(m_useUrpMaterial.isOn, vrm); VrmUtility.MetaCallback metaCallback = m_texts.UpdateMeta; var instance = await VrmUtility.LoadAsync(path, GetIAwaitCaller(m_useAsync.isOn), materialCallback, metaCallback, loadAnimation : m_loadAnimation.isOn); SetModel(instance); break; } case ".bvh": LoadMotion(path, File.ReadAllText(path)); break; } }
private async void Start() { var path = $"{Application.streamingAssetsPath}{uri}"; path = path.Replace("/", "\\"); if (!File.Exists(path)) { Debug.LogError($"Unable to find the glTF object at {path}"); } GltfObject gltfObject = null; try { gltfObject = await GltfUtility.ImportGltfObjectFromPathAsync(path); } catch (Exception e) { Debug.LogError($"{e.Message}\n{e.StackTrace}"); } if (gltfObject != null) { Debug.Log("Import successful"); } }
private async void Start() { var path = AbsolutePath; if (!File.Exists(path)) { Debug.LogError($"Unable to find the glTF object at {path}"); DebugText.SetActive(true); return; } DebugText.SetActive(false); GltfObject gltfObject = null; try { gltfObject = await GltfUtility.ImportGltfObjectFromPathAsync(path); // Put object in front of user gltfObject.GameObjectReference.transform.position = new Vector3(0.0f, 0.0f, 1.0f); gltfObject.GameObjectReference.transform.localScale *= this.ScaleFactor; } catch (Exception e) { Debug.LogError($"TestGltfLoading start failed - {e.Message}\n{e.StackTrace}"); } if (gltfObject != null) { Debug.Log("Import successful"); } }
private async void Start() { await new WaitForSeconds(5f); var gltfObject = await GltfUtility.ImportGltfObjectFromPathAsync($"{Application.dataPath}{uri}"); if (gltfObject != null) { Debug.Log("Import successful"); } }
/// <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); }
async void LoadModel(string path) { if (!File.Exists(path)) { return; } Debug.LogFormat("{0}", path); var instance = await Vrm10Utility.LoadAsync(path, true, m_useNormalization.isOn, awaitCaller : new RuntimeOnlyAwaitCaller(), materialGenerator : GetVrmMaterialDescriptorGenerator(m_useUrpMaterial.isOn), metaCallback : m_texts.UpdateMeta); if (instance == null) { // fallback to gltf instance = await GltfUtility.LoadAsync(path, awaitCaller : new RuntimeOnlyAwaitCaller()); } SetModel(instance); }
public IEnumerator TestGltfCustomAttributes() { // Load glTF string path = AssetDatabase.GUIDToAssetPath(AvocadoCustomAttrGuid); var task = GltfUtility.ImportGltfObjectFromPathAsync(path); yield return(WaitForTask(task)); GltfObject gltfObject = task.Result; yield return(null); // Check for custom attribute int temperatureIdx; gltfObject.meshes[0].primitives[0].Attributes.TryGetValue("_TEMPERATURE", out temperatureIdx); int temperature = gltfObject.accessors[temperatureIdx].count; Assert.AreEqual(100, temperature); }
/// <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; } }
public IEnumerator TestGltfLoads() { // Load glTF string path = AssetDatabase.GUIDToAssetPath(AvocadoCustomAttrGuid); var task = GltfUtility.ImportGltfObjectFromPathAsync(path); yield return(WaitForTask(task)); GltfObject gltfObject = task.Result; yield return(null); Assert.IsNotNull(gltfObject); Assert.AreEqual(1, gltfObject.meshes.Length); Assert.AreEqual(1, gltfObject.nodes.Length); // Check if mesh variables have been set by attributes Assert.AreEqual(406, gltfObject.meshes[0].Mesh.uv.Length); Assert.AreEqual(406, gltfObject.meshes[0].Mesh.normals.Length); Assert.AreEqual(406, gltfObject.meshes[0].Mesh.tangents.Length); Assert.AreEqual(406, gltfObject.meshes[0].Mesh.vertexCount); }
public IEnumerator TestGltfCustomAttributesData() { // Load glTF string path = AssetDatabase.GUIDToAssetPath(CubeCustomAttrGuid); var task = GltfUtility.ImportGltfObjectFromPathAsync(path); yield return(WaitForTask(task)); GltfObject gltfObject = task.Result; yield return(null); // Check for custom vertex data is a list of 10s gltfObject.meshes[0].primitives[0].Attributes.TryGetValue("_CUSTOM_ATTR", out var customAttrIdx); GltfAccessor accessor = gltfObject.GetAccessor(customAttrIdx); var intArray = accessor.GetIntArray(false); foreach (var item in intArray) { Assert.AreEqual(10, item); } }
private async void Start() { var path = $"{Application.streamingAssetsPath}{uri}"; path = path.Replace("/", "\\"); if (!File.Exists(path)) { Debug.LogError($"Unable to find the glTF object at {path}"); this.DebugText.SetActive(true); return; } this.DebugText.SetActive(false); GltfObject gltfObject = null; try { gltfObject = await GltfUtility.ImportGltfObjectFromPathAsync(path); // Put object in front of user gltfObject.GameObjectReference.transform.position = new Vector3(0.0f, 0.0f, 1.0f); gltfObject.GameObjectReference.transform.localScale *= this.ScaleFactor; } catch (Exception e) { Debug.LogError($"{e.Message}\n{e.StackTrace}"); } if (gltfObject != null) { Debug.Log("Import successful"); } }
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); } }
public static async void OnImportGltfAsset(AssetImportContext context) { var importedObject = await GltfUtility.ImportGltfObjectFromPathAsync(context.assetPath); if (importedObject == null || importedObject.GameObjectReference == null) { Debug.LogError("Failed to import glTF object"); return; } var gltfAsset = (GltfAsset)ScriptableObject.CreateInstance(typeof(GltfAsset)); gltfAsset.GltfObject = importedObject; gltfAsset.name = $"{gltfAsset.GltfObject.Name}{Path.GetExtension(context.assetPath)}"; gltfAsset.Model = importedObject.GameObjectReference; context.AddObjectToAsset("main", gltfAsset.Model); context.SetMainObject(importedObject.GameObjectReference); context.AddObjectToAsset("glTF data", gltfAsset); bool reImport = false; for (var i = 0; i < gltfAsset.GltfObject.textures?.Length; i++) { GltfTexture gltfTexture = gltfAsset.GltfObject.textures[i]; if (gltfTexture == null) { continue; } var path = AssetDatabase.GetAssetPath(gltfTexture.Texture); if (string.IsNullOrWhiteSpace(path)) { var textureName = gltfTexture.name; if (string.IsNullOrWhiteSpace(textureName)) { textureName = $"Texture_{i}"; gltfTexture.Texture.name = textureName; } context.AddObjectToAsset(textureName, gltfTexture.Texture); } else { if (!gltfTexture.Texture.isReadable) { var textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; if (textureImporter != null) { textureImporter.isReadable = true; textureImporter.SetPlatformTextureSettings(new TextureImporterPlatformSettings { format = TextureImporterFormat.RGBA32 }); textureImporter.SaveAndReimport(); reImport = true; } } } } if (reImport) { var importer = AssetImporter.GetAtPath(context.assetPath); importer.SaveAndReimport(); return; } for (var i = 0; i < gltfAsset.GltfObject.meshes?.Length; i++) { GltfMesh gltfMesh = gltfAsset.GltfObject.meshes[i]; string meshName = string.IsNullOrWhiteSpace(gltfMesh.name) ? $"Mesh_{i}" : gltfMesh.name; gltfMesh.Mesh.name = meshName; context.AddObjectToAsset($"{meshName}", gltfMesh.Mesh); } if (gltfAsset.GltfObject.materials != null) { foreach (GltfMaterial gltfMaterial in gltfAsset.GltfObject.materials) { context.AddObjectToAsset(gltfMaterial.name, gltfMaterial.Material); } } }
// 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); }
public static async void OnImportGltfAsset(AssetImportContext context) { var gltfAsset = (GltfAsset)ScriptableObject.CreateInstance(typeof(GltfAsset)); var importedObject = await GltfUtility.ImportGltfObjectFromPathAsync(context.assetPath); gltfAsset.GltfObject = importedObject; gltfAsset.name = $"{gltfAsset.GltfObject.Name}{Path.GetExtension(context.assetPath)}"; gltfAsset.Model = importedObject.GameObjectReference; context.AddObjectToAsset("main", gltfAsset.Model); context.SetMainObject(importedObject.GameObjectReference); context.AddObjectToAsset("glTF data", gltfAsset); bool reImport = false; for (var i = 0; i < gltfAsset.GltfObject.textures.Length; i++) { GltfTexture gltfTexture = gltfAsset.GltfObject.textures[i]; var path = AssetDatabase.GetAssetPath(gltfTexture.Texture); if (string.IsNullOrWhiteSpace(path)) { var textureName = gltfTexture.name; if (string.IsNullOrWhiteSpace(textureName)) { textureName = $"Texture_{i}"; gltfTexture.Texture.name = textureName; } context.AddObjectToAsset(textureName, gltfTexture.Texture); } else { if (!gltfTexture.Texture.isReadable) { var textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; textureImporter.isReadable = true; textureImporter.SetPlatformTextureSettings(new TextureImporterPlatformSettings { format = TextureImporterFormat.RGBA32 }); textureImporter.SaveAndReimport(); reImport = true; } } } if (reImport) { var importer = AssetImporter.GetAtPath(context.assetPath); importer.SaveAndReimport(); return; } for (var i = 0; i < gltfAsset.GltfObject.meshes.Length; i++) { GltfMesh gltfMesh = gltfAsset.GltfObject.meshes[i]; string meshName = string.IsNullOrWhiteSpace(gltfMesh.name) ? $"Mesh_{i}" : gltfMesh.name; gltfMesh.Mesh.name = meshName; context.AddObjectToAsset($"{meshName}", gltfMesh.Mesh); } foreach (GltfMaterial gltfMaterial in gltfAsset.GltfObject.materials) { if (context.assetPath.EndsWith(".glb")) { context.AddObjectToAsset(gltfMaterial.name, gltfMaterial.Material); } else { var path = Path.GetFullPath(Path.GetDirectoryName(context.assetPath)); path = path.Replace("\\", "/").Replace(Application.dataPath, "Assets"); path = $"{path}/{gltfMaterial.name}.mat"; AssetDatabase.CreateAsset(gltfMaterial.Material, path); gltfMaterial.Material = AssetDatabase.LoadAssetAtPath <Material>(path); } } }
async void LoadModel(string path) { if (!File.Exists(path)) { return; } _cancellationTokenSource?.Dispose(); _cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = _cancellationTokenSource.Token; try { Debug.LogFormat("{0}", path); var vrm10Instance = await Vrm10.LoadPathAsync(path, canLoadVrm0X : true, normalizeTransform : m_useNormalization.isOn, showMeshes : false, awaitCaller : m_useAsync.enabled?(IAwaitCaller) new RuntimeOnlyAwaitCaller() : (IAwaitCaller) new ImmediateCaller(), materialGenerator : GetVrmMaterialDescriptorGenerator(m_useUrpMaterial.isOn), vrmMetaInformationCallback : m_texts.UpdateMeta, ct : cancellationToken); if (vrm10Instance != null) { // test. error にならなければよい vrm10Instance.Runtime.Expression.SetWeight(ExpressionKey.Aa, 0); if (cancellationToken.IsCancellationRequested) { UnityObjectDestoyer.DestroyRuntimeOrEditor(vrm10Instance.gameObject); cancellationToken.ThrowIfCancellationRequested(); } SetModel(vrm10Instance.GetComponent <RuntimeGltfInstance>()); } else { // NOTE: load as glTF model if failed to load as VRM 1.0. // TODO: Hand over CancellationToken var gltfModel = await GltfUtility.LoadAsync(path, awaitCaller : m_useAsync.enabled?(IAwaitCaller) new RuntimeOnlyAwaitCaller() : (IAwaitCaller) new ImmediateCaller()); if (gltfModel == null) { throw new Exception("Failed to load the file as glTF format."); } if (cancellationToken.IsCancellationRequested) { gltfModel.Dispose(); cancellationToken.ThrowIfCancellationRequested(); } SetModel(gltfModel); } } catch (Exception ex) { if (ex is OperationCanceledException) { Debug.LogWarning($"Canceled to Load: {path}"); } else { Debug.LogError($"Failed to Load: {path}"); Debug.LogException(ex); } } }
/// <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."); } } }
/// <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="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; } } }