コード例 #1
0
        /// <summary>
        /// Queues queries for all known models around the requested bounds
        /// </summary>
        /// <param name="queryBounds"></param>
        public void QueueQueriesInBounds(ObjectAnchorsBoundingBox queryBounds)
        {
            List <ObjectQuery> nextQuerySet = new List <ObjectQuery>();

            SpatialGraph.SpatialGraphCoordinateSystem?coordinateSystem = ObjectAnchorsWorldManager.GlobalCoordinateSystem;
            if (!coordinateSystem.HasValue)
            {
                Debug.LogError("no coordinate system?");
                return;
            }

            foreach (TrackableObjectData tod in _trackableObjectDataLoader.TrackableObjects)
            {
                ObjectQuery nextQuery = _objectAnchorsService.CreateObjectQuery(tod.ModelId);

                nextQuery.MaxScaleChange = MaxScaleChange;

                if (tod.UseCustomParameters)
                {
                    nextQuery.MinSurfaceCoverage = tod.MinSurfaceCoverage;
                    nextQuery.IsExpectedToBeStandingOnGroundPlane     = tod.IsExpectedToBeStandingOnGroundPlane;
                    nextQuery.ExpectedMaxVerticalOrientationInDegrees = tod.ExpectedMaxVerticalOrientationInDegrees;
                    nextQuery.MaxScaleChange = tod.MaxScaleChange;
                }
                else
                {
                    nextQuery.MinSurfaceCoverage *= CoverageThresholdFactor;
                    nextQuery.ExpectedMaxVerticalOrientationInDegrees = AllowedVerticalOrientationInDegrees;
                }

                nextQuery.SearchAreas.Add(ObjectSearchArea.FromOrientedBox(
                                              coordinateSystem.Value,
                                              queryBounds.ToOuSdk())
                                          );

                nextQuerySet.Add(nextQuery);
            }

            _queryQueue.Enqueue(new Tuple <ObjectAnchorsBoundingBox, IEnumerable <ObjectQuery> >(queryBounds, nextQuerySet));
            Debug.Log($"{Time.frameCount} next query size {nextQuerySet.Count} query queue size {_queryQueue.Count} max scale change {MaxScaleChange} AllowedVerticalOrientationInDegrees {AllowedVerticalOrientationInDegrees}");
        }
コード例 #2
0
        public async Task <bool> LoadObjectModelsAsync(string modelPath)
        {
            IObjectAnchorsService objectAnchorsService = ObjectAnchorsService.GetService();

            Debug.Log($"{Application.persistentDataPath} {objectAnchorsService != null}");
            string[] ouFiles = Directory.GetFiles(modelPath, "*.ou", SearchOption.AllDirectories);
            foreach (var file in ouFiles)
            {
                // Represent a model by TrackableObject, and load its model into OU service.
                var trackableObject = new TrackableObjectData();

                trackableObject.ModelFilePath = file.Replace('/', '\\');

                trackableObject.ModelId = await objectAnchorsService.AddObjectModelAsync(trackableObject.ModelFilePath);

                if (trackableObject.ModelId != Guid.Empty)
                {
                    // Query the default coverage threshold from this object model.
                    ObjectQuery query = objectAnchorsService.CreateObjectQuery(trackableObject.ModelId);
                    trackableObject.MinSurfaceCoverageFromObjectModel = query.MinSurfaceCoverage;

                    trackableObject.ModelMesh          = GenerateMesh(trackableObject.ModelId);
                    trackableObject.logicalBoundingBox = objectAnchorsService.GetModelBoundingBox(trackableObject.ModelId);
                    _trackableObjects.Add(trackableObject);
                    _modelIdToTrackableObject.Add(trackableObject.ModelId, trackableObject);

                    Debug.Log($"Loaded Model\n{trackableObject}");
                }
                else
                {
                    Debug.LogError($"failed to load model {trackableObject.ModelFilePath}");
                }
            }
            if (_trackableObjects.Count > 0)
            {
                ModelsLoaded?.Invoke(this, EventArgs.Empty);
            }
            return(_trackableObjects.Count > 0);
        }
コード例 #3
0
    private Dictionary <Guid, ObjectQueryState> InitializeObjectQueries()
    {
        var objectQueries = new Dictionary <Guid, ObjectQueryState>();

        foreach (var modelId in _objectAnchorsService.ModelIds)
        {
            //
            // Create a query and set the parameters.
            //

            var queryState = new GameObject($"ObjectQueryState for model {modelId}").AddComponent <ObjectQueryState>();
            queryState.Query = _objectAnchorsService.CreateObjectQuery(modelId, ObservationMode);
            if (ShowEnvironmentObservations)
            {
                queryState.EnvironmentMaterial = EnvironmentMaterial;
            }

            objectQueries.Add(modelId, queryState);
        }

        return(objectQueries);
    }
コード例 #4
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;

        foreach (var modelId in _objectAnchorsService.ModelIds)
        {
            //
            // 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);

            //
            // Create a query and set the parameters.
            //

            var query = _objectAnchorsService.CreateObjectQuery(modelId);
            Debug.Assert(query != null);

            if (SearchAreaAsBoundingBox)
            {
                // 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.ToOuSdk()));
            }

            if (SearchAreaAsFieldOfView)
            {
                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.ToOuSdk()));
            }

            if (SearchAreaAsSphere)
            {
                // 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.ToOuSdk()));
            }

            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()));
    }