Jump to content

Gaze ray origin


Recommended Posts

Hi,

I am using SRanipal to collect and process gaze data, and several times in the process I have to use gaze rays, which I get with the provided method SRanipal_Eye_v2.GetGazeRay. Despite this method returning the origin of the ray, I have seen in several classes in the SDK that Camera.main.transform.position or Camera.main.transform.position - Camera.main.transform.up * 0.05f are used instead. I tried comparing both, and results are very similar, but not exactly the same, as shown below (in this example I simply get the gaze ray for combined eyes, raycast it in my scene, and display hits).

offset.png.396a380ddbe6053d7dc528cba7401b71.png

I am thus wondering which value should be used for optimal precision, as this is used in a scientific research and such offset is very impactful on the results.

 

I look forward to hearing back from you,

Regards,
Vivien

 

offset.png

Link to comment
Share on other sites

  • 1 year later...

"use the community developer forums" the support emails keep telling me.... then we try and no-one answers!

 

This is a very valid question that i am also wondering. SRAnipal seems a very bad SDK for gaze rays when it relies on us doing line traces to actually return results. Why can't it just return the vectors from the pupils themselves?

Link to comment
Share on other sites

  • 2 months later...

In my opinion, using the System Origin (Camera.main.transform.position) as the gaze origin in the World coordinate system is not a very good implementation.

I propose to use the corrected System Origin with the (local) gaze origin obtained by SRanipal_Eye_v2.GetGazeRay method as below, instead.

Using UnityEngine;
Using ViveSR.anipal.Eye;
...

SRanipal_Eye_v2.GetGazeRay(GazeIndex.LEFT, out Ray ray);     // w/o callback
Vector3 worldGazeOrigin = Camera.main.transform.position + Camera.main.transform.rotation * ray.origin;

Using above implementation, for example, the SRanipal_Eye_v2.Focus method can be modified as follows (the code before modification is commented out).

public static bool Focus(GazeIndex index, out Ray ray, out FocusInfo focusInfo, float radius, float maxDistance, int focusableLayer, EyeData_v2 eye_data)
{
    bool valid = GetGazeRay(index, out ray, eye_data);
    if (valid)
    {
        // rayGlobal = new Ray(Camera.main.transform.position, Camera.main.transform.TransformDirection(ray.direction));
      	Vector3 worldGazeOrigin = Camera.main.transform.position + Camera.main.transform.rotation * ray.origin;
        Ray rayGlobal = new Ray(worldGazeOrigin, Camera.main.transform.TransformDirection(ray.direction));
        RaycastHit hit;
        if (radius == 0) valid = Physics.Raycast(rayGlobal, out hit, maxDistance, focusableLayer);
        else valid = Physics.SphereCast(rayGlobal, radius, out hit, maxDistance, focusableLayer);
        focusInfo = new FocusInfo
        {
            point = hit.point,
            normal = hit.normal,
            distance = hit.distance,
            collider = hit.collider,
            rigidbody = hit.rigidbody,
            transform = hit.transform
        };
    }
    else
    {
        focusInfo = new FocusInfo();
    }
    return valid;
}

I can't vouch for the validity of the above implementation, but it seems to work better than the original implementation, at least for my project.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...