/// <summary> /// Polls for the result of pending ray cast requests. /// </summary> protected override void Update() { try { if (_instance.pendingQueries.Count > 0) { foreach (ulong handle in _instance.pendingQueries.Keys) { NativeBindings.MLRaycastResultNative raycastResult = NativeBindings.MLRaycastResultNative.Create(); MLResult.Code resultCode = NativeBindings.MLRaycastGetResult(_instance.trackerHandle, handle, ref raycastResult); if (resultCode == MLResult.Code.Ok) { _instance.completedQueries.Add(handle, raycastResult); } else if (resultCode != MLResult.Code.Pending) { MLPluginLog.ErrorFormat("MLRaycast.Update failed to get raycast result. Reason: {0}", MLResult.CodeToString(resultCode)); _instance.errorQueries.Add(handle); } } foreach (ulong handle in _instance.errorQueries) { _instance.pendingQueries.Remove(handle); } _instance.errorQueries.Clear(); foreach (KeyValuePair <ulong, NativeBindings.MLRaycastResultNative> handle in _instance.completedQueries) { // Check if there is a valid hit result. bool didHit = handle.Value.State != ResultState.RequestFailed && handle.Value.State != ResultState.NoCollision; _instance.pendingQueries[handle.Key]( handle.Value.State, didHit ? MLConvert.ToUnity(handle.Value.Hitpoint) : Vector3.zero, didHit ? MLConvert.ToUnity(handle.Value.Normal, true, false) : Vector3.zero, handle.Value.Confidence); _instance.pendingQueries.Remove(handle.Key); } _instance.completedQueries.Clear(); } } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLRaycast.Update failed. Reason: API symbols not found"); } }
/// <summary> /// Requests a ray cast with the given query parameters. /// </summary> /// <param name="query">Query parameters describing ray being cast.</param> /// <param name="callback">Delegate which will be called when the result of the ray cast is ready.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> public static MLResult Raycast(QueryParams query, OnRaycastResultDelegate callback) { try { if (MLRaycast.IsValidInstance()) { if (query == null || callback == null) { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed. Reason: Invalid input parameters."); return(MLResult.Create(MLResult.Code.InvalidParam)); } bool RequestRaycast() { if (MLRaycast.IsValidInstance()) { NativeBindings.MLRaycastQueryNative queryNative = new NativeBindings.MLRaycastQueryNative() { Position = MLConvert.FromUnity(query.Position), Direction = MLConvert.FromUnity(query.Direction, true, false), UpVector = MLConvert.FromUnity(query.UpVector, true, false), Width = query.Width, Height = query.Height, HorizontalFovDegrees = query.HorizontalFovDegrees, CollideWithUnobserved = query.CollideWithUnobserved, }; ulong requestHandle = MagicLeapNativeBindings.InvalidHandle; MLResult.Code resultCode = NativeBindings.MLRaycastRequest(_instance.trackerHandle, ref queryNative, ref requestHandle); if (resultCode != MLResult.Code.Ok) { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed to request a new ray cast. Reason: {0}", MLResult.CodeToString(resultCode)); return(true); } if (requestHandle == MagicLeapNativeBindings.InvalidHandle) { MLPluginLog.Error("MLRaycast.Raycast failed to request a new ray cast. Reason: Request handle is invalid."); return(true); } bool GetRaycastResults() { if (MLRaycast.IsValidInstance()) { NativeBindings.MLRaycastResultNative raycastResult = NativeBindings.MLRaycastResultNative.Create(); resultCode = NativeBindings.MLRaycastGetResult(_instance.trackerHandle, requestHandle, ref raycastResult); if (resultCode == MLResult.Code.Pending) { return(false); } if (resultCode == MLResult.Code.Ok) { // Check if there is a valid hit result. bool didHit = raycastResult.State != ResultState.RequestFailed && raycastResult.State != ResultState.NoCollision; MLThreadDispatch.ScheduleMain(() => { if (MLRaycast.IsValidInstance()) { callback( raycastResult.State, didHit ? MLConvert.ToUnity(raycastResult.Hitpoint) : Vector3.zero, didHit ? MLConvert.ToUnity(raycastResult.Normal, true, false) : Vector3.zero, raycastResult.Confidence); } else { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed. Reason: No Instance for MLRaycast"); } }); } else { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed to get raycast result. Reason: {0}", MLResult.CodeToString(resultCode)); } } else { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed. Reason: No Instance for MLRaycast"); } return(true); } MLThreadDispatch.ScheduleWork(GetRaycastResults); } else { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed. Reason: No Instance for MLRaycast"); } return(true); } MLThreadDispatch.ScheduleWork(RequestRaycast); return(MLResult.Create(MLResult.Code.Ok)); } else { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed. Reason: No Instance for MLRaycast"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLRaycast.Raycast failed. Reason: No Instance for MLRaycast")); } } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLRaycast.Raycast failed. Reason: API symbols not found"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLRaycast.Raycast failed. Reason: API symbols not found")); } }