Esempio n. 1
0
    IEnumerator RecordData()
    {
        while (true)
        {
            yield return(new WaitForEndOfFrame());

            if (recordingStopped)
            {
                continue;
            }

            RecordingDatum datum = new RecordingDatum
            {
                frameTime = Time.time,
                leftEye   = fove.GetLeftEyeVector(),
                rightEye  = fove.GetRightEyeVector()
            };

            dataSlice.Add(datum);

            if (dataSlice.Count >= writeAtDataCount)
            {
                if (!writingDataMutex.WaitOne(3))
                {
                    long excess = dataSlice.Count - writeAtDataCount;
                    if (excess > 1)
                    {
                        Debug.LogError("Data slice is " + excess + " entries over where it should be; this is" +
                                       "indicative of a major performance concern in the data recording and writing" +
                                       "process.");
                    }
                    continue;
                }
                CheckForNullDataToWrite();

                dataToWrite = dataSlice;
                dataSlice   = new List <RecordingDatum>((int)(writeAtDataCount + 1));

                writingDataMutex.ReleaseMutex();

                if (!threadWaitHandle.Set())
                {
                    Debug.LogError("Error setting the event to wake up the file writer thread!");
                }
            }
        }
    }
    private void RecordDatum(bool immediate)
    {
        // If recording is stopped (which is it by default), loop back around next frame.
        if (recordingStopped)
        {
            return;
        }

        if (!immediate)         // we run in the same thread as unity we can update the transformations in a synchronized way
        {
            UpdateFoveInterfaceMatrices(false);
        }

        Matrix4x4 transformMat;

        lock (foveInterfaceTransfo)
        {
            switch (raysCoordinateSpace)
            {
            case CoordinateSpace.World:
                transformMat = foveInterfaceTransfo.HMDToWorld;
                break;

            case CoordinateSpace.Local:
                transformMat = foveInterfaceTransfo.HMDToLocal;
                break;

            default:
                transformMat = Matrix4x4.identity;
                break;
            }
        }

        var leftEyeOffset  = FoveManager.GetLeftEyeOffset(immediate);
        var rightEyeOffset = FoveManager.GetRightEyeOffset(immediate);
        var leftEyeVector  = FoveManager.GetLeftEyeVector(immediate);
        var rightEyeVector = FoveManager.GetRightEyeVector(immediate);

        Ray leftRay, rightRay;

        Utils.CalculateGazeRays(ref transformMat, ref leftEyeVector, ref rightEyeVector, ref leftEyeOffset, ref rightEyeOffset, out leftRay, out rightRay);

        // If you add new fields, be sure to write them here.
        var datum = new RecordingDatum
        {
            frameTime = stopwatch.Elapsed.TotalSeconds,
            leftGaze  = leftRay,
            rightGaze = rightRay,
        };

        dataSlice.Add(datum);

        if (dataSlice.Count >= writeAtDataCount)
        {
            // Make sure we have exclusive access by locking the mutex, but only wait for up to 30 milliseconds.
            if (!writingDataMutex.WaitOne(30))
            {
                // If we got here, it means that we couldn't acquire exclusive access within the specified time
                // limit. Likely this means an error happened, but it could also mean that more data was being
                // written than it took to gather another set of data -- in which case you may need to extend the
                // timeout duration, though that will cause a noticeable frame skip in your application.

                // For now, the best thing we can do is continue the loop and try writing data again next frame.
                long excess = dataSlice.Count - writeAtDataCount;
                if (excess > 1)
                {
                    Debug.LogError("Data slice is " + excess + " entries over where it should be; this is" +
                                   "indicative of a major performance concern in the data recording and writing" +
                                   "process.");
                }
                return;
            }

            CheckForNullDataToWrite();

            // Move our current slice over to dataToWrite, and then create a new slice.
            dataToWrite = dataSlice;
            dataSlice   = new List <RecordingDatum>((int)(writeAtDataCount + 1));

            // Release our claim on the mutex.
            writingDataMutex.ReleaseMutex();

            if (!threadWaitHandle.Set())
            {
                Debug.LogError("Error setting the event to wake up the file writer thread");
            }
        }
    }
Esempio n. 3
0
    // The coroutine function which records data to the dataSlice List<> member
    IEnumerator RecordData()
    {
        // Inifinite loops are okay within coroutines because the "yield" statement pauses the function each time to
        // return control to the main program. Great for breaking tasks up into smaller chunks over time, or for doing
        // small amounts of work each frame but potentially outside of the normal Update cycle/call order.
        while (true)
        {
            // This statement pauses this function until Unity has finished rendering a frame. Inside the while loop,
            // this means that this function will resume from here every frame.
            yield return(new WaitForEndOfFrame());

            // If recording is stopped (which is it by default), loop back around next frame.
            if (recordingStopped)
            {
                continue;
            }

            // The FoveInterfaceBase.EyeRays struct contains world-space rays indicating eye gaze origin and direction,
            // so you don't necessarily need to record head position and orientation just to transform the gaze vectors
            // themselves. This data is pre-transformed for you.
            var rays = fove.GetGazeRays();

            // If you add new fields, be sure to write them here.
            RecordingDatum datum = new RecordingDatum
            {
                frameTime = Time.time,
                leftGaze  = rays.left,
                rightGaze = rays.right
            };

            dataSlice.Add(datum);

            if (dataSlice.Count >= writeAtDataCount)
            {
                // Make sure we have exclusive access by locking the mutex, but only wait for up to 30 milliseconds.
                if (!writingDataMutex.WaitOne(30))
                {
                    // If we got here, it means that we couldn't acquire exclusive access within the specified time
                    // limit. Likely this means an error happened, but it could also mean that more data was being
                    // written than it took to gather another set of data -- in which case you may need to extend the
                    // timeout duration, though that will cause a noticeable frame skip in your application.

                    // For now, the best thing we can do is continue the loop and try writing data again next frame.
                    long excess = dataSlice.Count - writeAtDataCount;
                    if (excess > 1)
                    {
                        Debug.LogError("Data slice is " + excess + " entries over where it should be; this is" +
                                       "indicative of a major performance concern in the data recording and writing" +
                                       "process.");
                    }
                    continue;
                }

                CheckForNullDataToWrite();

                // Move our current slice over to dataToWrite, and then create a new slice.
                dataToWrite = dataSlice;
                dataSlice   = new List <RecordingDatum>((int)(writeAtDataCount + 1));

                // Release our claim on the mutex.
                writingDataMutex.ReleaseMutex();

                if (!threadWaitHandle.Set())
                {
                    Debug.LogError("Error setting the event to wake up the file writer thread");
                }
            }
        }
    }