Forum Discussion

🚨 This forum is archived and read-only. To submit a forum post, please visit our new Developer Forum. 🚨
sh0v0r's avatar
sh0v0r
Protege
9 years ago

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.

2 Replies

Replies have been turned off for this discussion
  • 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;
    }
    }


  • "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. :)