Skip to main content
sh0v0r
Up and Coming
February 16, 2016

OVRRaycaster (Gaze UI) & GC Alloc

I have integrated the OVRInputModule provided in this blog post. https://developer.oculus.com/blog/unity ... tem-in-vr/

While inspecting the profiler I noticed the EventSystem which has the OVRInputModule on it, was generating 14.5k of memory per frame in my game.

Using the VRPointers demo scene from the blogs project and deep profiling I narrowed it down to the OVRRaycaster.RayIntersectsRectTransform() class as the culprit.
    This topic has been closed for replies.

    2 replies

    Inspiring
    February 16, 2016
    Thanks for pointing this out. The allocations in this function are unnecessary. To fix this you can replace the function with the following version. Note the new static variables at the top of the snippet.



    static private Plane rectPlane = new Plane();
    static Vector3[] rectCorners = new Vector3[4];

    /// <summary>
    /// Detects whether a ray intersects a RectTransform and if it does also
    /// returns the world position of the intersection.
    /// </summary>
    /// <param name="rectTransform"></param>
    /// <param name="ray"></param>
    /// <param name="worldPos"></param>
    /// <returns></returns>
    static bool RayIntersectsRectTransform(RectTransform rectTransform, Ray ray, out Vector3 worldPos)
    {

    rectTransform.GetWorldCorners(rectCorners);
    rectPlane.Set3Points(rectCorners[0], rectCorners[1], rectCorners[2]);

    float enter;
    if (!rectPlane.Raycast(ray, out enter))
    {
    worldPos = Vector3.zero;
    return false;
    }

    Vector3 intersection = ray.GetPoint(enter);

    Vector3 BottomEdge = rectCorners[3] - rectCorners[0];
    Vector3 LeftEdge = rectCorners[1] - rectCorners[0];
    float BottomDot = Vector3.Dot(intersection - rectCorners[0], BottomEdge);
    float LeftDot = Vector3.Dot(intersection - rectCorners[0], LeftEdge);
    if (BottomDot < BottomEdge.sqrMagnitude && // Can use sqrMag because BottomEdge is not normalized
    LeftDot < LeftEdge.sqrMagnitude &&
    BottomDot >= 0 &&
    LeftDot >= 0)
    {
    worldPos = rectCorners[0] + LeftDot * LeftEdge / LeftEdge.sqrMagnitude + BottomDot * BottomEdge / BottomEdge.sqrMagnitude;
    return true;
    }
    else
    {
    worldPos = Vector3.zero;
    return false;
    }
    }


    sh0v0r
    sh0v0rAuthor
    Up and Coming
    February 17, 2016
    "andyborrel" wrote:
    Thanks for pointing this out. The allocations in this function are unnecessary. To fix this you can replace the function with the following version. Note the new static variables at the top of the snippet.



    static private Plane rectPlane = new Plane();
    static Vector3[] rectCorners = new Vector3[4];

    /// <summary>
    /// Detects whether a ray intersects a RectTransform and if it does also
    /// returns the world position of the intersection.
    /// </summary>
    /// <param name="rectTransform"></param>
    /// <param name="ray"></param>
    /// <param name="worldPos"></param>
    /// <returns></returns>
    static bool RayIntersectsRectTransform(RectTransform rectTransform, Ray ray, out Vector3 worldPos)
    {

    rectTransform.GetWorldCorners(rectCorners);
    rectPlane.Set3Points(rectCorners[0], rectCorners[1], rectCorners[2]);

    float enter;
    if (!rectPlane.Raycast(ray, out enter))
    {
    worldPos = Vector3.zero;
    return false;
    }

    Vector3 intersection = ray.GetPoint(enter);

    Vector3 BottomEdge = rectCorners[3] - rectCorners[0];
    Vector3 LeftEdge = rectCorners[1] - rectCorners[0];
    float BottomDot = Vector3.Dot(intersection - rectCorners[0], BottomEdge);
    float LeftDot = Vector3.Dot(intersection - rectCorners[0], LeftEdge);
    if (BottomDot < BottomEdge.sqrMagnitude && // Can use sqrMag because BottomEdge is not normalized
    LeftDot < LeftEdge.sqrMagnitude &&
    BottomDot >= 0 &&
    LeftDot >= 0)
    {
    worldPos = rectCorners[0] + LeftDot * LeftEdge / LeftEdge.sqrMagnitude + BottomDot * BottomEdge / BottomEdge.sqrMagnitude;
    return true;
    }
    else
    {
    worldPos = Vector3.zero;
    return false;
    }
    }





    Cheers Andy, I had already gone ahead and made the exact same changes. :)