private Dictionary <long, Mesh> GetSurfaces()
    {
        Dictionary <long, Mesh> surfaces = new Dictionary <long, Mesh>();

        XRResponseRef r = GetCurrentReality();

        for (int i = 0; i < r.ptr.surfacesSetSurfacesCount; ++i)
        {
            // Extract basic info about this mesh.
            long id = r.ptr.surfacesSetSurfacesIdTimeMicros[i];

            int beginFaceIndex     = r.ptr.surfacesSetSurfacesFacesBeginIndex[i];
            int endFaceIndex       = r.ptr.surfacesSetSurfacesFacesEndIndex[i];
            int beginVerticesIndex = r.ptr.surfacesSetSurfacesVerticesBeginIndex[i];
            int endVerticesIndex   = r.ptr.surfacesSetSurfacesVerticesEndIndex[i];

            // Build the vertex and normal arrays.
            int       nVertices = endVerticesIndex - beginVerticesIndex;
            Vector3[] vertices  = new Vector3[nVertices];
            Vector3[] normals   = new Vector3[nVertices];
            Vector2[] uvs       = new Vector2[nVertices];
            for (int j = 0; j < nVertices; ++j)
            {
                int vertexIndex = (beginVerticesIndex + j) * 3;
                vertices[j] = RecenterAndScale(
                    new Vector3(
                        r.ptr.surfacesSetVertices[vertexIndex],
                        r.ptr.surfacesSetVertices[vertexIndex + 1],
                        r.ptr.surfacesSetVertices[vertexIndex + 2]));
                normals[j] = Vector3.up;
                float u = vertices[j][0];
                float v = vertices[j][2];
                uvs[j] = new Vector2(u, v);
            }

            // We can just directly copy over the triangles (they are stored in consecutive sets of three
            // vertex indices) as long as we offset the vertex indices.
            int   nFaces    = endFaceIndex - beginFaceIndex;
            int[] triangles = new int[nFaces * 3];
            for (int j = 0; j < nFaces; ++j)
            {
                int v0 = r.ptr.surfacesSetFaces[3 * (j + beginFaceIndex)] - beginVerticesIndex;
                int v1 = r.ptr.surfacesSetFaces[3 * (j + beginFaceIndex) + 1] - beginVerticesIndex;
                int v2 = r.ptr.surfacesSetFaces[3 * (j + beginFaceIndex) + 2] - beginVerticesIndex;
                triangles[3 * j]     = v0;
                triangles[3 * j + 1] = v1;
                triangles[3 * j + 2] = v2;
            }

            Mesh mesh = new Mesh();
            mesh.vertices  = vertices;
            mesh.normals   = normals;
            mesh.uv        = uvs;
            mesh.triangles = triangles;

            surfaces.Add(id, mesh);
        }

        return(surfaces);
    }
    public Matrix4x4 GetCameraIntrinsics()
    {
        XRResponseRef r  = GetCurrentReality();
        Matrix4x4     np = Matrix4x4.zero;

        if (cam != null)
        {
            np = cam.projectionMatrix;
        }

        if (r == null || r.ptr.cameraIntrinsicMatrix44f == null)
        {
            return(np);
        }

        float[] intrinsics = r.ptr.cameraIntrinsicMatrix44f;

        for (int i = 0; i < 4; ++i)
        {
            for (int j = 0; j < 4; ++j)
            {
                np[i, j] = intrinsics[j * 4 + i];
            }
        }

        return(np);
    }
 private XRResponseRef GetCurrentReality()
 {
     if (currentXRResponse == null || currentRealityUpdateNumber < updateNumber)
     {
         currentRealityUpdateNumber = updateNumber;
         currentXRResponse          = bridge.GetCurrentRealityXR();
     }
     return(currentXRResponse);
 }
    public Quaternion GetCameraRotation()
    {
        XRResponseRef r = GetCurrentReality();

        return(new Quaternion(
                   r.ptr.cameraExtrinsicRotationX,
                   r.ptr.cameraExtrinsicRotationY,
                   r.ptr.cameraExtrinsicRotationZ,
                   r.ptr.cameraExtrinsicRotationW));
    }
    public Vector3 GetCameraPosition()
    {
        XRResponseRef r = GetCurrentReality();

        return(RecenterAndScale(
                   new Vector3(
                       r.ptr.cameraExtrinsicPositionX,
                       r.ptr.cameraExtrinsicPositionY,
                       r.ptr.cameraExtrinsicPositionZ)));
    }
    void Update()
    {
        if (!explicitlyPaused)
        {
            RunIfPaused();
        }

        updateNumber++;

        XRResponseRef r = GetCurrentReality();

        if (lastRealityMicros >= r.ptr.eventIdTimeMicros)
        {
            return;
        }
        lastRealityMicros = r.ptr.eventIdTimeMicros;

        if (realityTexture != null)
        {
            bridge.RenderFrameForDisplay();
        }
    }
    public long GetActiveSurfaceId()
    {
        XRResponseRef r = GetCurrentReality();

        return(r.ptr.surfacesActiveSurfaceIdTimeMicros);
    }
    public float GetLightExposure()
    {
        XRResponseRef r = GetCurrentReality();

        return(r.ptr.lightingGlobalExposure);
    }