Exemple #1
0
        //------------------------------------------------------------------------/
        // Routines
        //------------------------------------------------------------------------/
        bool ScanForInteractables()
        {
            Collider[] castResults       = Physics.OverlapSphere(this.scanPosition, this.range);
            var        interactions      = new List <InteractionQuery>();
            bool       foundInteractions = false;

            // The scan event that will be sent
            var scanEvent = new DetectionEvent();

            scanEvent.sensor = this;

            if (castResults != null)
            {
                foreach (var hit in castResults)
                {
                    // Check whether it can be detected, depending on the scanmode
                    bool detected = Detect(hit.transform);
                    if (!detected)
                    {
                        continue;
                    }

                    // Check whether it is an interactable
                    var interactable = hit.transform.gameObject.GetComponent <Interactable>();
                    if (interactable == null)
                    {
                        continue;
                    }

                    // Scan it
                    interactable.gameObject.Dispatch <DetectionEvent>(scanEvent);

                    // Create a query object, filling with scanned data
                    var query = new InteractionQuery();
                    query.data         = scanEvent.scanData;
                    query.distance     = Vector3.Distance(root.position, hit.transform.position);
                    query.interactable = interactable;

                    // Now store the interaction
                    interactions.Add(query);

                    // Note that we have scanned something
                    foundInteractions = true;
                }
            }

            // Sort the interactions by the closest one
            interactions.Sort((a, b) => a.distance.CompareTo(b.distance));
            // Save the current interactions
            interactivesInRange = interactions.ToArray();

            // Now inform the agent of the current results
            var scanResult = new DetectionResultEvent();

            scanResult.hasFoundInteractions = foundInteractions;
            this.gameObject.Dispatch <DetectionResultEvent>(scanResult);
            return(foundInteractions);
        }
Exemple #2
0
    private void HandleQuery(InteractionQuery query)
    {
        // NOTE: this method is called from a worker thread, so it must not access any game objects.

        try
        {
            // The mechanism that we use for getting the window ID assumes that the game window is on top
            // when the scripts start running. It usually does the right thing, but not always.
            // So adjust if necessary.
            var queryWindowIdEnum = query.WindowIds.GetEnumerator();
            if (queryWindowIdEnum.MoveNext())
            {
                if (queryWindowIdEnum.Current != ScreenHelpers.Instance.GameWindowId)
                {
                    print(string.Format("Window ID mismatch: queried for {0}, expected {1}. Adjusting.", queryWindowIdEnum.Current, ScreenHelpers.Instance.GameWindowId));
                    ScreenHelpers.Instance.GameWindowId = queryWindowIdEnum.Current;
                    _gameWindowPosition = new Vector2(float.NaN, float.NaN);
                }
            }

            if (float.IsNaN(_gameWindowPosition.x))
            {
                // We don't have a valid game window position, so we cannot respond to any queries at this time.
                return;
            }

            // Get query bounds and map them to GUI coordinates.
            double boundsX, boundsY, boundsWidth, boundsHeight;
            query.Bounds.TryGetRectangularData(out boundsX, out boundsY, out boundsWidth, out boundsHeight);
            var queryRectInGuiCoordinates = new Rect(
                (float)(boundsX - _gameWindowPosition.x),
                (float)(boundsY - _gameWindowPosition.y),
                (float)boundsWidth,
                (float)boundsHeight);

            // Make a copy of the collection of interactors to avoid race conditions.
            List<EyeXInteractor> interactorsCopy;
            lock (_lock)
            {
                interactorsCopy = new List<EyeXInteractor>(_interactors.Values);
            }

            // Create the snapshot and add the interactors that intersect with the query bounds.
            var snapshot = _context.CreateSnapshotWithQueryBounds(query);
            snapshot.AddWindowId(ScreenHelpers.Instance.GameWindowId);
            foreach (var interactor in interactorsCopy)
            {
                if (interactor.IntersectsWith(queryRectInGuiCoordinates))
                {
                    interactor.AddToSnapshot(snapshot, ScreenHelpers.Instance.GameWindowId, _gameWindowPosition);
                }
            }

            // Commit the snapshot.
            snapshot.CommitAsync(null);
        }
        catch (InteractionApiException ex)
        {
            print("EyeX query handler failed: " + ex.Message);
        }
    }
 /// <summary>
 /// Handles a query from the EyeX Engine.
 /// Note that this method is called from a worker thread, so it may not access any WPF Window objects.
 /// </summary>
 /// <param name="query">Query.</param>
 private void HandleQuery(InteractionQuery query)
 {
     var queryBounds = query.Bounds;
     double x, y, w, h;
     if (queryBounds.TryGetRectangularData(out x, out y, out w, out h))
     {
         // marshal the query to the UI thread, where WPF objects may be accessed.
         System.Windows.Rect r = new System.Windows.Rect((int)x, (int)y, (int)w, (int)h);
         this.Dispatcher.BeginInvoke(new Action<System.Windows.Rect>(HandleQueryOnUiThread), r);
     }
 }