static void Main(string[] args) { // create the native custom adapter var adapter = new AdapterFuncs(); // create the interaction library Tobii.InteractionLib.IInteractionLib intlib = Tobii.InteractionLib.InteractionLibFactory.CreateInteractionLib( Tobii.InteractionLib.FieldOfUse.Interactive, adapter.Handle); Console.WriteLine("Starting interaction library update loop."); // setup and maintain device connection, wait for device data between events and // update interaction library to trigger all callbacks, stop after 10 cycles const int max_cycles = 10; var cycle = 0; while (cycle++ < max_cycles) { intlib.WaitAndUpdate(); } // cleanup - here done explicitly with Dispose(). The alternative is to use a using statement, // which implicitly disposes an instance when the scope is left. intlib.Dispose(); adapter.Dispose(); }
static void Main(string[] args) { // create the interaction library Tobii.InteractionLib.IInteractionLib intlib = Tobii.InteractionLib.InteractionLibFactory.CreateInteractionLib( Tobii.InteractionLib.FieldOfUse.Interactive); // assume single screen with size 2560x1440 and use full screen (not window local) coordinates const float width = 2560.0f; const float height = 1440.0f; const float offset = 0.0f; intlib.CoordinateTransformAddOrUpdateDisplayArea(width, height); intlib.CoordinateTransformSetOriginOffset(offset, offset); // subscribe to gaze point data; print data to console when called intlib.GazePointDataEvent += evt => { Console.WriteLine( "x: " + evt.x + ", y: " + evt.y + ", validity: " + (evt.validity == Tobii.InteractionLib.Validity.Valid ? "valid" : "invalid") + ", timestamp: " + evt.timestamp_us + " us" ); }; Console.WriteLine("Starting interaction library update loop."); // setup and maintain device connection, wait for device data between events and // update interaction library to trigger all callbacks, stop after 200 cycles const int max_cycles = 200; var cycle = 0; while (cycle++ < max_cycles) { intlib.WaitAndUpdate(); } // cleanup - here done explicitly with Dispose(). The alternative is to use a using statement, // which implicitly disposes an instance when the scope is left. intlib.Dispose(); }
static void Main(string[] args) { // create the interaction library Tobii.InteractionLib.IInteractionLib intlib = Tobii.InteractionLib.InteractionLibFactory.CreateInteractionLib( Tobii.InteractionLib.FieldOfUse.Interactive); // assume single screen with size 2560x1440 and use full screen (not window local) coordinates const float width = 2560.0f; const float height = 1440.0f; const float offset = 0.0f; intlib.CoordinateTransformAddOrUpdateDisplayArea(width, height); intlib.CoordinateTransformSetOriginOffset(offset, offset); // setup ids and rectangles that define the interactors we want to use (one in each corner of the screen), // then add them to the interaction library const ulong idA = 0; const ulong idB = 1; const ulong idC = 2; const ulong idD = 3; const float size = 500.0f; var rectA = new Tobii.InteractionLib.Rectangle(0, 0, size, size); var rectB = new Tobii.InteractionLib.Rectangle(width - size, 0, size, size); var rectC = new Tobii.InteractionLib.Rectangle(0, height - size, size, size); var rectD = new Tobii.InteractionLib.Rectangle(width - size, height - size, size, size); const float z = 0.0f; intlib.BeginInteractorUpdates(); intlib.AddOrUpdateInteractor(idA, rectA, z); intlib.AddOrUpdateInteractor(idB, rectB, z); intlib.AddOrUpdateInteractor(idC, rectC, z); intlib.AddOrUpdateInteractor(idD, rectD, z); intlib.CommitInteractorUpdates(); // this is used to keep track of focus events (See below) ulong focusId = ulong.MaxValue - 1; uint focusCount = 0; // subscribe to gaze focus events // print event data to console when called and count the number of consecutive focus events intlib.GazeFocusEvent += e => { Console.WriteLine("Interactor: {0}, focused: {1}, timestamp: {2} us", e.interactorId, e.hasFocus, e.timestamp_us); if (e.hasFocus) { focusCount = focusId == e.interactorId ? focusCount + 1 : 1; focusId = e.interactorId; } }; // setup and maintain device connection, wait for device data between events and // update interaction library to trigger all callbacks // stop after 3 consecutive focus events on the same interactor Console.WriteLine("Starting interaction library update loop."); const uint MaxFocusCount = 3; while (focusCount < MaxFocusCount) { intlib.WaitAndUpdate(); } Console.WriteLine("Interactor {0} got focused {1} times", focusId, focusCount); // cleanup - here done explicitly with Dispose(). The alternative is to use a using statement, // which implicitly disposes an instance when the scope is left. intlib.Dispose(); }
static void Main() { // create the interaction library Tobii.InteractionLib.IInteractionLib intlib = Tobii.InteractionLib.InteractionLibFactory.CreateInteractionLib( Tobii.InteractionLib.FieldOfUse.Interactive); // EnumerateDisplayAreas will enumerate all displays on the windows machine, including their // virtual screen bounds and display IDs, and put the results into an IList<MonitorDisplayArea>. // The display IDs have the same formatting as are used on Tobii eyetrackers to // identify which display they are attached to. foreach (var area in DisplayEnumerationHelper.DisplayEnumerationHelper.EnumerateDisplayAreas()) { // For each display we tell the Interaction Library // 1) the coordinate scaling we want to use by giving the size as we see it // 2) the size and origin in virtual screen coordinates, and // 3) the ID of the display. // // Interaction Library will use this information to map connected devices to display areas, // to transform all data streams when outputting them and to properly transform all added // interactors to its internal, global coordinate space when performing gaze focus calculations. // // Here we are using the native scaling (so first to parameters are the same as the virtual // screen size) but we could have used any scaling we like, eg (1.0, 1.0) for relative // coordinates. intlib.CoordinateTransformAddOrUpdateDisplayArea( area.wVirtual, area.hVirtual, area.wVirtual, area.hVirtual, area.xVirtual, area.yVirtual, area.monitorId); } var form = new Form(); form.Text = "Interactor Window"; // By telling the Interaction Library to offset the coordinate system origin // so that it matches the location of the window client area, we can add and // update interactors using window-local coordinates. // The origin offset has to be in the virtual coordinate space we used when // adding the display areas above. form.Move += (sender, e) => { var offset = form.PointToScreen(new Point(0, 0)); intlib.CoordinateTransformSetOriginOffset(offset.X, offset.Y); }; // In this sample we want the entire window client area to be an interactor // that changes color when it gets and loses gaze focus. void AddOrUpdateInteractor(Size clientSize) { var rect = new Tobii.InteractionLib.Rectangle(0, 0, clientSize.Width, clientSize.Height); intlib.BeginInteractorUpdates(); intlib.AddOrUpdateInteractor(0, rect, 0); intlib.CommitInteractorUpdates(); }; form.Resize += (sender, e) => AddOrUpdateInteractor(form.ClientSize); // Subscribe to gaze focus events. When the form client area (which is an // interactor) gets or loses gaze focus, set the form color accordingly. intlib.GazeFocusEvent += e => form.BackColor = e.hasFocus ? SystemColors.Highlight : SystemColors.Window; var closed = false; form.Closed += (sender, e) => closed = true; // Now that all events and subscriptions are set up, the physical form can be created. form.Show(); AddOrUpdateInteractor(form.ClientSize); // Handle window events and update interaction library to trigger all callbacks while (!closed) { Application.DoEvents(); intlib.Update(); } intlib.Dispose(); }