private void TrySearchObject() { if (Interlocked.CompareExchange(ref _detectionCompleted, 0, 1) == 1) { if (_cachedCameraMain == null) { _cachedCameraMain = Camera.main; } var cameraLocation = new ObjectAnchorsLocation { Position = _cachedCameraMain.transform.position, Orientation = _cachedCameraMain.transform.rotation, }; var coordinateSystem = ObjectAnchorsWorldManager.GlobalCoordinateSystem; Task.Run(async() => { try { await DetectObjectAsync(coordinateSystem, cameraLocation); } catch (Exception ex) { UnityEngine.WSA.Application.InvokeOnAppThread(() => { TextLogger.Log($"Detection failed. Exception message: {ex.ToString()}"); }, false); } Interlocked.CompareExchange(ref _detectionCompleted, 1, 0); }); } }
private Task DetectObjectAsync(Microsoft.Azure.ObjectAnchors.SpatialGraph.SpatialGraphCoordinateSystem?coordinateSystem, ObjectAnchorsLocation cameraLocation) { // // Coordinate system may not be available at this time, try it later. // if (!coordinateSystem.HasValue) { return(Task.CompletedTask); } // // Get camera location and coordinate system. // var cameraForward = cameraLocation.Orientation * Vector3.forward; var estimatedTargetLocation = new ObjectAnchorsLocation { Position = cameraLocation.Position + cameraForward * SearchFrustumFarDistance * 0.5f, Orientation = Quaternion.Euler(0.0f, cameraLocation.Orientation.eulerAngles.y, 0.0f), }; // // Remove detected objects far away from the camera. // foreach (var instance in _objectAnchorsService.TrackingResults) { var location = instance.Location; if (location.HasValue) { var modelBbox = _objectAnchorsService.GetModelBoundingBox(instance.ModelId); Debug.Assert(modelBbox.HasValue); // Compute the coordinate of instance bounding box center in Unity world. var instancePosition = location.Value.Position + location.Value.Orientation * modelBbox.Value.Center; var offset = instancePosition - cameraLocation.Position; if (offset.magnitude > SearchFrustumFarDistance * 1.5f) { _objectAnchorsService.RemoveObjectInstance(instance.InstanceId); } } } // // Detect object(s) in field of view, bounding box, or sphere. // var objectQueries = new List <Microsoft.Azure.ObjectAnchors.ObjectQuery>(); var trackingResults = _objectAnchorsService.TrackingResults; lock (_objectQueries) foreach (var objectQuery in _objectQueries) { var modelId = objectQuery.Key; var query = objectQuery.Value.Query; // // Optionally skip a model detection if an instance is already found. // if (SearchSingleInstance) { if (trackingResults.Where(r => r.ModelId == modelId).Count() > 0) { continue; } } var modelBox = _objectAnchorsService.GetModelBoundingBox(modelId); Debug.Assert(modelBox.HasValue); query.SearchAreas.Clear(); switch (SearchAreaShape) { case SearchAreaKind.Box: { // Adapt bounding box size to model size. Note that Extents.z is model's height. float modelXYSize = new Vector2(modelBox.Value.Extents.x, modelBox.Value.Extents.y).magnitude; var boundingBox = new ObjectAnchorsBoundingBox { Center = estimatedTargetLocation.Position, Orientation = estimatedTargetLocation.Orientation, Extents = new Vector3(modelXYSize * SearchAreaScaleFactor, modelBox.Value.Extents.z * SearchAreaScaleFactor, modelXYSize * SearchAreaScaleFactor), }; query.SearchAreas.Add( Microsoft.Azure.ObjectAnchors.ObjectSearchArea.FromOrientedBox( coordinateSystem.Value, boundingBox.ToSpatialGraph())); break; } case SearchAreaKind.FieldOfView: { var fieldOfView = new ObjectAnchorsFieldOfView { Position = cameraLocation.Position, Orientation = cameraLocation.Orientation, FarDistance = SearchFrustumFarDistance, HorizontalFieldOfViewInDegrees = SearchFrustumHorizontalFovInDegrees, AspectRatio = SearchFrustumAspectRatio, }; query.SearchAreas.Add( Microsoft.Azure.ObjectAnchors.ObjectSearchArea.FromFieldOfView( coordinateSystem.Value, fieldOfView.ToSpatialGraph())); break; } case SearchAreaKind.Sphere: { // Adapt sphere radius to model size. float modelDiagonalSize = modelBox.Value.Extents.magnitude; var sphere = new ObjectAnchorsSphere { Center = estimatedTargetLocation.Position, Radius = modelDiagonalSize * 0.5f * SearchAreaScaleFactor, }; query.SearchAreas.Add( Microsoft.Azure.ObjectAnchors.ObjectSearchArea.FromSphere( coordinateSystem.Value, sphere.ToSpatialGraph())); break; } } objectQueries.Add(query); } // // Pause a while if detection is not required. // if (objectQueries.Count == 0) { Thread.Sleep(100); return(Task.CompletedTask); } // // Run detection. // // Add event to the queue. _objectAnchorsEventQueue.Enqueue( new ObjectAnchorsServiceEvent { Kind = ObjectAnchorsServiceEventKind.DetectionAttempted, Args = null }); return(_objectAnchorsService.DetectObjectAsync(objectQueries.ToArray())); }