To get started with eye tracking in your application you must first grab the StreamEngine library, there are two ways of integrating the library in your application, depending on your use case and preferred programming language. If you are using Visual Studio and coding in C++/C# then the NuGet Package Manager in Visual Studio is your friend. Or if you prefer a makefile based building system you can download the archive containing the library and all necessary header files. Here we will have a detailed look at the two ways of integrating StreamEngine in your app.

Visual Studio and the NuGet package manager

The NuGet package manager is a great and convenient way to add third-party libraries to your application, such as the Tobii StreamEngine. There are two flavors available of the StreamEngine NuGet package; Tobii.StreamEngine which includes C# Interops for use in a C# .NET application and Tobii.StreamEngine.Native which includes library and C header files intended for native C/C++ applications.

You install the package in two easy steps in Visual Studio:

  • Right-click on the project’s reference folder and choose Manage NuGet Packages… from the menu.
  • Browse for the StreamEngine package and click install on the package of your choosing. Notice that the packaging.config has been added/updated in the project folder.

You are now ready to start using StreamEngine in your application. Check out the super simple sample below.

Makefile project

For those that are using a makefile based build systems, there is an easy way to integrate StreamEngine into your application:

  • Download the StreamEngine zip archive, here, and extract it into your prereqs subfolder of your project. The subfolder should include a lib directory which contains the tobii_stream_engine.dll for x86 and x64 architecture and an include directory featuring all necessary header files.
  • Then you need to setup the library and include paths for StreamEngine.
    • Add a library search directory (i.e ${PREREQS}/tobii/lib/${ARCH})
    • Add include directory of header files (i.e ${PREREQS}/tobii/include)
  • Link your application with tobii_stream_engine dynamic library.

Now you are all set to start using StreamEngine in your application. Check out the super simple sample bellow or move on to our more advanced best practices samples and Api documentation.

Super simple C# .NET application


using Tobii.StreamEngine;
namespace Tobii.StreamEngine.Sample
{
    public static class StreamSamples
    {
        private static void ProcessCallbackFunction(Object deviceContextObject)
        {
            IntPtr deviceContext = (IntPtr)deviceContextObject;
            Console.WriteLine("Press return to exit");

            while (!Console.KeyAvailable)
            {
                Interop.tobii_wait_for_callbacks(IntPtr.Zero, new [] { deviceContext });
                Interop.tobii_device_process_callbacks(deviceContext);
            }
        }

        public static void RunBareMetal()
        {
            tobii_error_t result;
            IntPtr apiContext;
            result = Interop.tobii_api_create(out apiContext, null);
            Helpers.PrintIfError("Initialize", result);

            List urls;
            result = Interop.tobii_enumerate_local_device_urls(apiContext, out urls);
            Helpers.PrintIfError("EnumerateLocalDeviceUrls", result);
            if(urls.Count == 0)
                Console.WriteLine("Error: No device(s) found\n");

            IntPtr deviceContext;
            result = Interop.tobii_device_create(apiContext, urls[0], out deviceContext);
            Helpers.PrintIfError("CreateContext", result);

            Thread processCallbackThread = new Thread( 
                new ParameterizedThreadStart(ProcessCallbackFunction));
            processCallbackThread.IsBackground = true;
            processCallbackThread.Name = "Process Callback Thread";
            processCallbackThread.Start(deviceContext);

            result = Interop.tobii_gaze_point_subscribe(deviceContext, OnGazePoint);
            Helpers.PrintIfError("SubscribeGazePoint", result);

            // -->> Wait for the thread here <<--
            while (processCallbackThread.IsAlive);

            result = Interop.tobii_gaze_point_unsubscribe(deviceContext);
            Helpers.PrintIfError("UnsubscribeGazePoint", result);
            result = Interop.tobii_device_destroy(deviceContext);
            Helpers.PrintIfError("DestroyDevice", result);
            result = Interop.tobii_api_destroy(apiContext);
            Helpers.PrintIfError("DestroyApi", result);
        }
    }
}

Super simple C++ Application


#include <tobii/tobii.h>
#include <tobii/tobii_streams.h>
#include <stdio.h>
#include <assert.h>

void gaze_point_callback( tobii_gaze_point_t const* gaze_point, void* user_data )
{
    if( gaze_point->validity == TOBII_VALIDITY_VALID )
        printf( "Gaze point: %f, %f\n",
            gaze_point->position_xy[ 0 ],
            gaze_point->position_xy[ 1 ] );
}

static void url_receiver( char const* url, void* user_data )
{
    char* buffer = (char*)user_data;
    if( *buffer != '\0' ) return; // only keep first value

    if( strlen( url ) < 256 )
        strcpy( buffer, url );
}

int main()
{
    tobii_api_t* api;
    tobii_error_t error = tobii_api_create( &api, NULL, NULL );
    assert( error == TOBII_ERROR_NO_ERROR );

    char url[ 256 ] = { 0 };
    error = tobii_enumerate_local_device_urls( api, url_receiver, url );
    assert( error == TOBII_ERROR_NO_ERROR && *url != '\0' );

    tobii_device_t* device;
    error = tobii_device_create( api, url, &device );
    assert( error == TOBII_ERROR_NO_ERROR );

    error = tobii_gaze_point_subscribe( device, gaze_point_callback, 0 );
    assert( error == TOBII_ERROR_NO_ERROR );

    int is_running = 1000; // in this sample, exit after some iterations
    while( --is_running > 0 )
    {
        error = tobii_wait_for_callbacks( NULL, 1, &device );
        assert( error == TOBII_ERROR_NO_ERROR || error == TOBII_ERROR_TIMED_OUT );

        error = tobii_device_process_callbacks( device );
        assert( error == TOBII_ERROR_NO_ERROR );
    }

    error = tobii_gaze_point_unsubscribe( device );
    assert( error == TOBII_ERROR_NO_ERROR );

    error = tobii_device_destroy( device );
    assert( error == TOBII_ERROR_NO_ERROR );

    error = tobii_api_destroy( api );
    assert( error == TOBII_ERROR_NO_ERROR );
    return 0;
}

Analytical Use

Tobii’s consumer eye trackers are primarily intended for personal interaction use and not for analytical purposes. Any application that stores or transfers eye tracking data must have a special license from Tobii.