protected override async Task OnDiscoverCoordinatesAsync(CancellationToken cancellationToken, int[] idsToLocate) { DebugLog($"OnDiscoverCoordinateAsync, CanBeCanceled:{cancellationToken.CanBeCanceled}, IsCancellationRequested:{cancellationToken.IsCancellationRequested}"); if (idsToLocate == null || idsToLocate.Length < 1) { UnityEngine.Debug.LogError($"{nameof(MarkerVisualCoordinateService)} depends on ids so that it could visualize them, at least one should be provided."); return; } DebugLog($"Creating spatial coordinate {idsToLocate[0]}"); SpatialCoordinate markerCoordinate = new SpatialCoordinate(idsToLocate[0], markerVisual); OnNewCoordinate(markerCoordinate.Id, markerCoordinate); DebugLog($"Showing marker"); markerCoordinate.ShowMarker(); DebugLog($"Waiting for cancellation token: CanBeCanceled:{cancellationToken.CanBeCanceled}, IsCancellationRequested:{cancellationToken.IsCancellationRequested}"); await Task.WhenAny(Task.Delay(-1, cancellationToken)); markerCoordinate.WorldToCoordinate = cameraTransform.localToWorldMatrix * cameraToMarker; DebugLog($"Hiding marker"); markerCoordinate.HideMarker(); }
/// <inheritdoc /> public override async Task <ISpatialCoordinate> LocalizeAsync(CancellationToken cancellationToken) { localizer.DebugLog("Getting host coordinate"); ISpatialCoordinate spatialCoordinate = null; using (var cancellableCTS = CancellationTokenSource.CreateLinkedTokenSource(defaultCancellationToken, cancellationToken)) { await coordinateService.TryDiscoverCoordinatesAsync(cancellationToken, new int[] { settings.TopMarkerID, settings.MiddleMarkerID, settings.BottomMarkerID }); if (!coordinateService.TryGetKnownCoordinate(settings.TopMarkerID, out ISpatialCoordinate topSpatialCoordinate) || !coordinateService.TryGetKnownCoordinate(settings.MiddleMarkerID, out ISpatialCoordinate middleSpatialCoordinate) || !coordinateService.TryGetKnownCoordinate(settings.BottomMarkerID, out ISpatialCoordinate bottomSpatialCoordinate)) { Debug.LogError("Unexpected failure to discover a marker coordinate"); } else { var topPosition = topSpatialCoordinate.CoordinateToWorldSpace(Vector3.zero); var middlePosition = middleSpatialCoordinate.CoordinateToWorldSpace(Vector3.zero); var bottomPosition = bottomSpatialCoordinate.CoordinateToWorldSpace(Vector3.zero); // Find the point that is at the T intersection of the three markers by projecting the middle marker // onto the top-bottom line segment var markerIntersection = bottomPosition + Vector3.Project(middlePosition - bottomPosition, topPosition - bottomPosition); // Create a stable rotation for the overall marker using the plane formed by the three // individual markers. The order of points passed to the Plane constructor is important to // ensure the normal direction is the correct direction to create the quaternion. var markerPlane = new Plane(topPosition, middlePosition, bottomPosition); var markerRotation = Quaternion.LookRotation(markerPlane.normal, bottomPosition - topPosition); spatialCoordinate = new SpatialCoordinate(markerIntersection, markerRotation); } } return(spatialCoordinate); }