text:
//-----------------------------------------------------------------------
// <copyright file="Frame.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCore
{
    using System;
    using System.Collections.Generic;
    using GoogleARCoreInternal;
    using UnityEngine;

    /// <summary>
    /// Provides a snapshot of the state of ARCore at a specific timestamp associated with the current frame.  Frame
    /// holds information about ARCore's state including tracking status, the pose of the camera relative to the world,
    /// estimated lighting parameters, and information on updates to objects (like Planes or Point Clouds) that ARCore
    /// is tracking.
    /// </summary>
    public class Frame
    {
        //// @cond EXCLUDE_FROM_DOXYGEN

        private static List<TrackableHit> s_TmpTrackableHitList = new List<TrackableHit>();

        //// @endcond

        /// <summary>
        /// Gets the pose of the ARCore device for the frame in Unity world coordinates.
        /// </summary>
        public static Pose Pose
        {
            get
            {
                var nativeSession = LifecycleManager.Instance.NativeSession;
                if (nativeSession == null)
                {
                    return Pose.identity;
                }

                var cameraHandle = nativeSession.FrameApi.AcquireCamera();
                Pose result = nativeSession.CameraApi.GetPose(cameraHandle);
                nativeSession.CameraApi.Release(cameraHandle);
                return result;
            }
        }

        /// <summary>
        /// Gets the current light estimate for this frame.
        /// </summary>
        public static LightEstimate LightEstimate
        {
            get
            {
                // TODO (b/73256094): Remove isTracking when fixed.
                var nativeSession = LifecycleManager.Instance.NativeSession;
                var isTracking = LifecycleManager.Instance.SessionStatus == SessionStatus.Tracking;
                if (nativeSession == null || !isTracking)
                {
                    return new LightEstimate(LightEstimateState.NotValid, 0.0f, Color.black);
                }

                return nativeSession.FrameApi.GetLightEstimate();
            }
        }

        /// <summary>
        /// Performs a raycast against physical objects being tracked by ARCore.
        /// Output the closest hit from the camera.
        /// Note that the Unity's screen coordinate (0, 0)
        /// starts from bottom left.
        /// </summary>
        /// <param name="x">Horizontal touch position in Unity's screen coordiante.</param>
        /// <param name="y">Vertical touch position in Unity's screen coordiante.</param>
        /// <param name="filter">A filter bitmask where each {@link TrackableHitFlag} which is set represents a category
        /// of raycast hits the method call should consider valid.</param>
        /// <param name="hitResult">A {@link TrackableHit} that will be set if the raycast is successful.</param>
        /// <returns><c>true</c> if the raycast had a hit, otherwise <c>false</c>.</returns>
        public static bool Raycast(float x, float y, TrackableHitFlags filter,
            out TrackableHit hitResult)
        {
            hitResult = new TrackableHit();
            var nativeSession = LifecycleManager.Instance.NativeSession;
            if (nativeSession == null)
            {
                return false;
            }

            // Note that the Unity's screen coordinate (0, 0) starts from bottom left.
            bool foundHit = nativeSession.HitTestApi.Raycast(nativeSession.FrameHandle, x, Screen.height - y, filter,
                s_TmpTrackableHitList, true);

            if (foundHit && s_TmpTrackableHitList.Count != 0)
            {
                hitResult = s_TmpTrackableHitList[0];
            }

            return foundHit;
        }

        /// <summary>
        /// Performs a raycast against physical objects being tracked by ARCore.
        /// Output all hits from the camera.
        /// Note that the Unity's screen coordinate (0, 0)
        /// starts from bottom left.
        /// </summary>
        /// <param name="x">Horizontal touch position in Unity's screen coordiante.</param>
        /// <param name="y">Vertical touch position in Unity's screen coordiante.</param>
        /// <param name="filter">A filter bitmask where each {@link TrackableHitFlag} which is set represents a category
        /// of raycast hits the method call should consider valid.</param>
        /// <param name="hitResults">A list of {@link TrackableHit} that will be set if the raycast is successful.</param>
        /// <returns><c>true</c> if the raycast had a hit, otherwise <c>false</c>.</returns>
        public static bool RaycastAll(float x, float y, TrackableHitFlags filter, List<TrackableHit> hitResults)
        {
            hitResults.Clear();
            var nativeSession = LifecycleManager.Instance.NativeSession;
            if (nativeSession == null)
            {
                return false;
            }

            return nativeSession.HitTestApi.Raycast(nativeSession.FrameHandle, x, Screen.height - y, filter, hitResults, true);
        }

        /// <summary>
        /// Container for state related to the ARCore camera image metadata for the Frame.
        /// </summary>
        public static class CameraMetadata
        {
            /// <summary>
            /// Get camera image metadata value. The querying value type needs to match the returned type.
            /// The type could be checked in CameraMetadata.cs.
            /// </summary>
            /// <param name="metadataTag">Metadata type.</param>
            /// <param name="outMetadataList">Result list of the requested values.</param>
            /// <returns><c>true</c> if getting metadata value successfully, otherwise <c>false</c>.</returns>
            public static bool TryGetValues(CameraMetadataTag metadataTag, List<CameraMetadataValue> outMetadataList)
            {
                outMetadataList.Clear();
                var nativeSession = LifecycleManager.Instance.NativeSession;
                if (nativeSession == null)
                {
                    return false;
                }

                var metadataHandle = nativeSession.FrameApi.AcquireImageMetadata();
                var isSuccess = nativeSession.CameraMetadataApi.TryGetValues(metadataHandle, metadataTag, outMetadataList);
                nativeSession.CameraMetadataApi.Release(metadataHandle);
                return isSuccess;
            }

            /// <summary>
            /// Get all available tags in the current frame's metadata.
            /// </summary>
            /// <param name="outMetadataTags">Result list of the tags.</param>
            /// <returns><c>true</c> if getting tags successfully, otherwise <c>false</c>.</returns>
            public static bool GetAllCameraMetadataTags(List<CameraMetadataTag> outMetadataTags)
            {
                outMetadataTags.Clear();
                var nativeSession = LifecycleManager.Instance.NativeSession;
                if (nativeSession == null)
                {
                    return false;
                }

                var metadataHandle = nativeSession.FrameApi.AcquireImageMetadata();
                var isSuccess = nativeSession.CameraMetadataApi.GetAllCameraMetadataTags(metadataHandle,
                    outMetadataTags);
                nativeSession.CameraMetadataApi.Release(metadataHandle);
                return isSuccess;
            }
        }

        /// <summary>
        /// Container for state related to the ARCore point cloud for the Frame.
        /// </summary>
        public static class PointCloud
        {
            /// <summary>
            /// Gets a value indicating whether new point cloud data became available in the current frame.
            /// </summary>
            /// <returns><c>true</c> if new point cloud data became available in the current frame, otherwise
            /// <c>false</c>.</returns>
            public static bool IsUpdatedThisFrame
            {
                get
                {
                    var nativeSession = LifecycleManager.Instance.NativeSession;
                    if (nativeSession == null)
                    {
                        return false;
                    }

                    return nativeSession.IsPointCloudNew;
                }
            }

            /// <summary>
            /// Gets the count of point cloud points in the frame.
            /// </summary>
            public static int PointCount
            {
                get
                {
                    // TODO (b/73256094): Remove isTracking when fixed.
                    var nativeSession = LifecycleManager.Instance.NativeSession;
                    var isTracking = LifecycleManager.Instance.SessionStatus == SessionStatus.Tracking;
                    if (nativeSession == null || !isTracking)
                    {
                        return 0;
                    }

                     return nativeSession.PointCloudApi.GetNumberOfPoints(nativeSession.PointCloudHandle);
                }
            }

            /// <summary>
            /// Gets a point from the point cloud at a given index.
            /// The point returned will be a Vector4 in the form <x,y,z,c> where the first three dimensions describe
            /// the position of the point in the world and the last represents a confidence estimation in the range [0, 1).
            /// </summary>
            /// <param name="index">The index of the point cloud point to get.</param>
            /// <returns>The point from the point cloud at <c>index</c> along with its confidence.</returns>
            public static Vector4 GetPoint(int index)
            {
                var nativeSession = LifecycleManager.Instance.NativeSession;
                if (nativeSession == null)
                {
                    return Vector4.zero;
                }

                return nativeSession.PointCloudApi.GetPoint(nativeSession.PointCloudHandle, index);
            }

            /// <summary>
            /// Copies the point cloud into the supplied parameter <c>points</c>.
            /// Each point will be a Vector4 in the form <x,y,z,c> where the first three dimensions describe the position
            /// of the point in the world and the last represents a confidence estimation in the range [0, 1).
            /// </summary>
            /// <param name="points">A list that will be filled with point cloud points by this method call.</param>
            public static void CopyPoints(List<Vector4> points)
            {
                points.Clear();
                var nativeSession = LifecycleManager.Instance.NativeSession;
                if (nativeSession == null)
                {
                    return;
                }

                nativeSession.PointCloudApi.CopyPoints(nativeSession.PointCloudHandle, points);
            }
        }

        /// <summary>
        /// Container for state related to the ARCore camera for the frame.
        /// </summary>
        public static class CameraImage
        {
            /// <summary>
            /// Gets a texture used from the device's rear camera.
            /// </summary>
            public static Texture Texture
            {
                get
                {
                    return LifecycleManager.Instance.BackgroundTexture;
                }
            }

            /// <summary>
            /// Gets UVs that map the orienation and aspect ratio of <c>Frame.CameraImage.Texture</c> that of the
            /// device's display.
            /// </summary>
            public static DisplayUvCoords DisplayUvCoords
            {
                get
                {
                    ApiDisplayUvCoords displayUvCoords = new ApiDisplayUvCoords(new Vector2(0, 1),
                        new Vector2(1, 1), new Vector2(0, 0), new Vector2(1, 0));

                    var nativeSession = LifecycleManager.Instance.NativeSession;
                    if (nativeSession == null || Texture == null)
                    {
                        return displayUvCoords.ToDisplayUvCoords();
                    }

                    nativeSession.FrameApi.TransformDisplayUvCoords(ref displayUvCoords);
                    return displayUvCoords.ToDisplayUvCoords();
                }
            }

            /// <summary>
            /// Attempts to acquire the camera image for CPU access.
            /// </summary>
            /// <returns>A <c>CameraImageBytes</c> struct with <c>IsAvailable</c> property set to <c>true</c> if
            /// successful and <c>false</c> if the image could not be acquired.</returns>
            public static GoogleARCore.CameraImageBytes AcquireCameraImageBytes()
            {
                var nativeSession = LifecycleManager.Instance.NativeSession;
                if (nativeSession == null)
                {
                    return new CameraImageBytes(IntPtr.Zero);
                }

                return nativeSession.FrameApi.AcquireCameraImageBytes();
            }

            /// <summary>
            /// Gets the projection matrix for the frame.
            /// </summary>
            /// <param name="nearClipping">The near clipping plane for the projection matrix.</param>
            /// <param name="farClipping">The far clipping plane for the projection matrix.</param>
            /// <returns>The projection matrix for the frame.</returns>
            public static Matrix4x4 GetCameraProjectionMatrix(float nearClipping, float farClipping)
            {
                var nativeSession = LifecycleManager.Instance.NativeSession;
                if (nativeSession == null || Texture == null)
                {
                    return Matrix4x4.identity;
                }

                var cameraHandle = nativeSession.FrameApi.AcquireCamera();
                var result = nativeSession.CameraApi.GetProjectionMatrix(cameraHandle, nearClipping, farClipping);
                nativeSession.CameraApi.Release(cameraHandle);
                return result;
            }
        }
    }
}


text:
//-----------------------------------------------------------------------
// <copyright file="SessionStatusExtensions.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCore
{
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;

    /// <summary>
    /// Extension methods for the SessionStatus enumeration.
    /// </summary>
    public static class SessionStatusExtensions
    {
        private const int k_NotInitializedGroupStart = 0;
        private const int k_ValidSessionGroupStart = 100;
        private const int k_ErrorGroupStart = 200;

        /// <summary>
        /// Gets whether a SessionStatus is not yet initialized.
        /// </summary>
        /// <param name="status">The SessionStatus to check.</param>
        /// <returns><c>true</c> if the SessionStatus is not initialized, otherwise <c>false</c>.</returns>
        public static bool IsNotInitialized(this SessionStatus status)
        {
            int normalizedValue = (int)status - k_NotInitializedGroupStart;
            return normalizedValue >= 0 && normalizedValue < 100;
        }

        /// <summary>
        /// Gets whether a SessionStatus is initialized and valid.
        /// </summary>
        /// <param name="status">The SessionStatus to check.</param>
        /// <returns><c>true</c> if the SessionStatus is initialized and valid,
        /// otherwise <c>false</c>.</returns>
        public static bool IsValid(this SessionStatus status)
        {
            int normalizedValue = (int)status - k_ValidSessionGroupStart;
            return normalizedValue >= 0 && normalizedValue < 100;
        }

        /// <summary>
        /// Gets whether a SessionStatus is an error.
        /// </summary>
        /// <param name="status">The SessionStatus to check.</param>
        /// <returns><c>true</c> if the SessionStatus is an error,
        /// otherwise <c>false</c>.</returns>
        public static bool IsError(this SessionStatus status)
        {
            int normalizedValue = (int)status - k_ErrorGroupStart;
            return normalizedValue >= 0 && normalizedValue < 100;
        }
    }
}

repo_name: jonas-johansson/ARCoreUtils

repo_language: C#

mime_type: text/plain


text:
//-----------------------------------------------------------------------
// <copyright file="TrackedPointOrientationMode.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCore
{
    /// <summary>
    /// The orientation mode for a TrackedPoint.
    /// </summary>
    public enum TrackedPointOrientationMode
    {
        Identity = 0,
        SurfaceNormal = 1,
    }
}


text:
fileFormatVersion: 2
guid: cfb05be3ca34b4826b62df99f182da2b
folderAsset: yes
timeCreated: 1518226182
licenseType: Pro
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: f24ed3047ed4646bfab6a8a530dc432c
timeCreated: 1510947955
licenseType: Free
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: 30a41262cba2646c98f6d3cf4e46fb2a
timeCreated: 1516741153
licenseType: Pro
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
//-----------------------------------------------------------------------
// <copyright file="TrackableHitFlags.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCore
{
    using System;
    using UnityEngine;

    /// <summary>
    /// Flags representing categories of raycast hits.
    /// </summary>
    [Flags]
    public enum TrackableHitFlags
    {
        /// <summary>
        /// This value is returned on a TrackableHit to indicate no collision occurred.
        ///
        /// If you pass this into Raycast, you will not get any collision results.
        /// </summary>
        None = 0,

        /// <summary>
        /// The collision is within the the TrackedPlane's convex bounding polygon.
        /// </summary>
        PlaneWithinPolygon = 1 << 0,

        /// <summary>
        /// The collision is within the TrackedPlane's bounding box.
        /// </summary>
        PlaneWithinBounds = 1 << 1,

        /// <summary>
        /// The collision is on the TrackedPlane, but not limited to the bounding box or polygon.
        /// This acts as if the plane extends out to infinity.
        /// </summary>
        PlaneWithinInfinity = 1 << 2,

        /// <summary>
        /// The collision is on a feature point in the current frame's point cloud.
        /// </summary>
        FeaturePoint = 1 << 3,

        /// <summary>
        /// The collision is on a feature point in the current frame's point cloud
        /// that has a surface normal estimate (orientation).
        /// </summary>
        FeaturePointWithSurfaceNormal = 1 << 4,
    }
}


text:
//-----------------------------------------------------------------------
// <copyright file="CameraMetadataValue.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCore
{
    using System;
    using System.Runtime.InteropServices;
    using GoogleARCoreInternal;
    using UnityEngine;

    /// <summary>
    /// Struct to contain camera metadata's value. When querying data from the struct, caller is responsible
    /// for making sure the querying data type matches the ValueType.
    ///
    /// For example: if ValueType is typeof(byte), caller should only use
    /// CameraMetadataValue.AsByte() to access the value.
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    public struct CameraMetadataValue
    {
        [FieldOffset(0)]
        private NdkCameraMetadataType m_Type;
        [FieldOffset(4)]
        private sbyte m_ByteValue;
        [FieldOffset(4)]
        private int m_IntValue;
        [FieldOffset(4)]
        private long m_LongValue;
        [FieldOffset(4)]
        private float m_FloatValue;
        [FieldOffset(4)]
        private double m_DoubleValue;
        [FieldOffset(4)]
        private CameraMetadataRational m_RationalValue;

        /// <summary>
        /// Constructs CameraMetadataValue using sbyte. This constructor only sets the sbyte field
        /// in the struct, leaving the rest of the data to default value.
        /// </summary>
        /// <param name="byteValue">The byte value set to the struct.</param>
        public CameraMetadataValue(sbyte byteValue)
        {
            m_IntValue = 0;
            m_LongValue = 0;
            m_FloatValue = 0;
            m_DoubleValue = 0;
            m_RationalValue = new CameraMetadataRational();

            m_Type = NdkCameraMetadataType.Byte;
            m_ByteValue = byteValue;
        }

        /// <summary>
        /// Constructs CameraMetadataValue using int. This constructor only sets the int field
        /// in the struct, leaving the rest of the data to default value.
        /// </summary>
        /// <param name="intValue">The int value set to the struct.</param>
        public CameraMetadataValue(int intValue)
        {
            m_ByteValue = 0;
            m_LongValue = 0;
            m_FloatValue = 0;
            m_DoubleValue = 0;
            m_RationalValue = new CameraMetadataRational();

            m_Type = NdkCameraMetadataType.Int32;
            m_IntValue = intValue;
        }

        /// <summary>
        /// Constructs CameraMetadataValue using long. This constructor only sets the long field
        /// in the struct, leaving the rest of the data to default value.
        /// </summary>
        /// <param name="longValue">The long value set to the struct.</param>
        public CameraMetadataValue(long longValue)
        {
            m_ByteValue = 0;
            m_IntValue = 0;
            m_FloatValue = 0;
            m_DoubleValue = 0;
            m_RationalValue = new CameraMetadataRational();

            m_Type = NdkCameraMetadataType.Int64;
            m_LongValue = longValue;
        }

        /// <summary>
        /// Constructs CameraMetadataValue using float. This constructor only sets the float field
        /// in the struct, leaving the rest of the data to default value.
        /// </summary>
        /// <param name="floatValue">The float value set to the struct.</param>
        public CameraMetadataValue(float floatValue)
        {
            m_ByteValue = 0;
            m_IntValue = 0;
            m_LongValue = 0;
            m_DoubleValue = 0;
            m_RationalValue = new CameraMetadataRational();

            m_Type = NdkCameraMetadataType.Float;
            m_FloatValue = floatValue;
        }

        /// <summary>
        /// Constructs CameraMetadataValue using double. This constructor only sets the double field
        /// in the struct, leaving the rest of the data to default value.
        /// </summary>
        /// <param name="doubleValue">The double value set to the struct.</param>
        public CameraMetadataValue(double doubleValue)
        {
            m_ByteValue = 0;
            m_IntValue = 0;
            m_LongValue = 0;
            m_FloatValue = 0;
            m_RationalValue = new CameraMetadataRational();

            m_Type = NdkCameraMetadataType.Double;
            m_DoubleValue = doubleValue;
        }

        /// <summary>
        /// Constructs CameraMetadataValue using CameraMetadataRational. This constructor only sets the CameraMetadataRational field
        /// in the struct, leaving the rest of the data to default value.
        /// </summary>
        /// <param name="rationalValue">The CameraMetadataRational value set to the struct.</param>
        public CameraMetadataValue(CameraMetadataRational rationalValue)
        {
            m_ByteValue = 0;
            m_IntValue = 0;
            m_LongValue = 0;
            m_FloatValue = 0;
            m_DoubleValue = 0;

            m_Type = NdkCameraMetadataType.Rational;
            m_RationalValue = rationalValue;
        }

        /// <summary>
        /// Gets the Type of the CameraMetadataValue. This Type must be used to call the proper query function.
        /// </summary>
        public Type ValueType
        {
            get
            {
                switch (m_Type)
                {
                case NdkCameraMetadataType.Byte:
                    return typeof(Byte);
                case NdkCameraMetadataType.Int32:
                    return typeof(int);
                case NdkCameraMetadataType.Float:
                    return typeof(float);
                case NdkCameraMetadataType.Int64:
                    return typeof(long);
                case NdkCameraMetadataType.Double:
                    return typeof(double);
                case NdkCameraMetadataType.Rational:
                    return typeof(CameraMetadataRational);
                default:
                    return null;
                }
            }
        }

        /// <summary>
        /// Gets sbyte value from the struct. This function checks if the querying type matches the internal
        /// type field, and logs error if the types do not match.
        /// </summary>
        /// <returns>Returns sbyte value stored in the struct.</returns>
        public sbyte AsByte()
        {
            if (m_Type != NdkCameraMetadataType.Byte)
            {
                LogError(NdkCameraMetadataType.Byte);
            }

            return m_ByteValue;
        }

        /// <summary>
        /// Gets int value from the struct. This function checks if the querying type matches the internal
        /// type field, and logs error if the types do not match.
        /// </summary>
        /// <returns>Returns int value stored in the struct.</returns>
        public int AsInt()
        {
            if (m_Type != NdkCameraMetadataType.Int32)
            {
                LogError(NdkCameraMetadataType.Int32);
            }

            return m_IntValue;
        }

        /// <summary>
        /// Gets float value from the struct. This function checks if the querying type matches the internal
        /// type field, and logs error if the types do not match.
        /// </summary>
        /// <returns>Returns float value stored in the struct.</returns>
        public float AsFloat()
        {
            if (m_Type != NdkCameraMetadataType.Float)
            {
                LogError(NdkCameraMetadataType.Float);
            }

            return m_FloatValue;
        }

        /// <summary>
        /// Gets long value from the struct. This function checks if the querying type matches the internal
        /// type field, and logs error if the types do not match.
        /// </summary>
        /// <returns>Returns long value stored in the struct.</returns>
        public long AsLong()
        {
            if (m_Type != NdkCameraMetadataType.Int64)
            {
                LogError(NdkCameraMetadataType.Int64);
            }

            return m_LongValue;
        }

        /// <summary>
        /// Gets double value from the struct. This function checks if the querying type matches the internal
        /// type field, and logs error if the types do not match.
        /// </summary>
        /// <returns>Returns double value stored in the struct.</returns>
        public double AsDouble()
        {
            if (m_Type != NdkCameraMetadataType.Double)
            {
                LogError(NdkCameraMetadataType.Double);
            }

            return m_DoubleValue;
        }

        /// <summary>
        /// Gets CameraMetadataRational value from the struct. This function checks if the querying type matches the internal
        /// type field, and logs error if the types do not match.
        /// </summary>
        /// <returns>Returns CameraMetadataRational value stored in the struct.</returns>
        public CameraMetadataRational AsRational()
        {
            if (m_Type != NdkCameraMetadataType.Rational)
            {
                LogError(NdkCameraMetadataType.Rational);
            }

            return m_RationalValue;
        }

        private void LogError(NdkCameraMetadataType requestedType)
        {
            ARDebug.LogErrorFormat("Error getting value from CameraMetadataType due to type mismatch. " +
                    "requested type = {0}, internal type = {1}\n" +
                    "Are you sure you are querying the correct type?", requestedType, m_Type);
        }
    }

    /// <summary>
    /// CameraMetadataRational follows the layout of ACameraMetadata_rational struct in NDK.
    /// Please refer to NdkCameraMetadata.h for documentation:
    /// https://developer.android.com/ndk/reference/ndk_camera_metadata_8h.html .
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct CameraMetadataRational
    {
        /// <summary>
        /// The numerator of the metadata rational.
        /// </summary>
        public int Numerator;

        /// <summary>
        /// The denominator of the metadata rational.
        /// </summary>
        public int Denominator;
    }
}


text:
//-----------------------------------------------------------------------
// <copyright file="TrackableManager.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using GoogleARCore;
    using UnityEngine;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
     Justification = "Internal")]
    public class TrackableManager
    {
        private Dictionary<IntPtr, Trackable> m_TrackableDict =
            new Dictionary<IntPtr, Trackable>(new IntPtrEqualityComparer());

        private NativeSession m_NativeSession;

        private int m_LastUpdateFrame = -1;

        private List<Trackable> m_NewTrackables = new List<Trackable>();

        private List<Trackable> m_AllTrackables  = new List<Trackable>();

        private List<Trackable> m_UpdatedTrackables  = new List<Trackable>();

        private HashSet<Trackable> m_OldTrackables  = new HashSet<Trackable>();

        public TrackableManager(NativeSession nativeSession)
        {
            m_NativeSession = nativeSession;
        }

        /// <summary>
        /// Factory method for creating and reusing TrackedPlane references from native handles.
        /// </summary>
        /// <param name="nativeHandle">A native handle to a plane that has been acquired.  RELEASE WILL BE HANDLED BY
        /// THIS METHOD.</param>
        /// <returns>A reference to a tracked plane. </returns>
        public Trackable TrackableFactory(IntPtr nativeHandle)
        {
            if (nativeHandle == IntPtr.Zero)
            {
                return null;
            }

            Trackable result;
            if (m_TrackableDict.TryGetValue(nativeHandle, out result))
            {
                // Release aquired handle and return cached result.
                m_NativeSession.TrackableApi.Release(nativeHandle);
                return result;
            }

            ApiTrackableType trackableType = m_NativeSession.TrackableApi.GetType(nativeHandle);
            if (trackableType == ApiTrackableType.Plane)
            {
                result = new TrackedPlane(nativeHandle, m_NativeSession);
            }
            else if (trackableType == ApiTrackableType.Point)
            {
                result = new TrackedPoint(nativeHandle, m_NativeSession);
            }
            else
            {
                UnityEngine.Debug.LogFormat("Cant find {0}", trackableType);
                throw new NotImplementedException("TrackableFactory:: No constructor for requested trackable type.");
            }

            m_TrackableDict.Add(nativeHandle, result);
            return result;
        }

        public void GetTrackables<T>(List<T> trackables, TrackableQueryFilter filter) where T : Trackable
        {
            if (m_LastUpdateFrame < Time.frameCount)
            {
                // Get trackables updated this frame.
                m_NativeSession.FrameApi.GetUpdatedTrackables(m_UpdatedTrackables);

                // Get all the trackables in the session.
                m_NativeSession.SessionApi.GetAllTrackables(m_AllTrackables);

                // Find trackables that are not in the hashset (new).
                m_NewTrackables.Clear();
                for (int i = 0; i < m_AllTrackables.Count; i++)
                {
                    Trackable trackable = m_AllTrackables[i];
                    if (!m_OldTrackables.Contains(trackable))
                    {
                        m_NewTrackables.Add(trackable);
                        m_OldTrackables.Add(trackable);
                    }
                }

                m_LastUpdateFrame = Time.frameCount;
            }

            trackables.Clear();

            if (filter == TrackableQueryFilter.All)
            {
                for (int i = 0; i < m_AllTrackables.Count; i++)
                {
                    _SafeAdd<T>(m_AllTrackables[i], trackables);
                }
            }
            else if (filter == TrackableQueryFilter.New)
            {
                for (int i = 0; i < m_NewTrackables.Count; i++)
                {
                    _SafeAdd<T>(m_NewTrackables[i], trackables);
                }
            }
            else if (filter == TrackableQueryFilter.Updated)
            {
                for (int i = 0; i < m_UpdatedTrackables.Count; i++)
                {
                    _SafeAdd<T>(m_UpdatedTrackables[i], trackables);
                }
            }
        }

        private void _SafeAdd<T>(Trackable trackable, List<T> trackables) where T : Trackable
        {
            if (trackable is T)
            {
                trackables.Add(trackable as T);
            }
        }
    }
}


text:
//-----------------------------------------------------------------------
// <copyright file="LifecycleManager.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.InteropServices;
    using GoogleARCore;
    using UnityEngine;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
     Justification = "Internal")]
    public class LifecycleManager
    {
        private static LifecycleManager s_Instance = new LifecycleManager();

        private CheckApkAvailabilityResultCallback m_CheckApkAvailabilityResultCallback;

        private RequestApkInstallationResultCallback m_RequestApkInstallationResultCallback;

        private CameraPermissionRequestProvider m_RequestCameraPermissionCallback;

        private EarlyUpdateCallback m_EarlyUpdateCallback;

        private Texture2D m_BackgroundTexture;

        private ARCoreSession m_SessionComponent;

        private NativeSession m_NativeSession;

        private List<Action<ApkAvailabilityStatus>> m_PendingAvailabilityCheckCallbacks =
            new List<Action<ApkAvailabilityStatus>>();

        private List<Action<ApkInstallationStatus>> m_PendingInstallationRequestCallbacks =
            new List<Action<ApkInstallationStatus>>();

        static LifecycleManager()
        {
            Instance._Initialize();
        }

        private delegate void CheckApkAvailabilityResultCallback(ApiAvailability status,
            IntPtr context);

        private delegate void RequestApkInstallationResultCallback(
            ApiApkInstallationStatus status, IntPtr context);

        private delegate void CameraPermissionsResultCallback(bool granted,
            IntPtr context);

        private delegate void CameraPermissionRequestProvider(
            CameraPermissionsResultCallback onComplete, IntPtr context);

        private delegate void SessionCreationResultCallback(
            IntPtr sessionHandle, IntPtr frameHandle, IntPtr context, ApiArStatus status);

        private delegate void EarlyUpdateCallback();

        public static LifecycleManager Instance
        {
            get
            {
                return s_Instance;
            }
        }

        public Texture2D BackgroundTexture
        {
            get
            {
                return m_BackgroundTexture;
            }
        }

        public NativeSession NativeSession
        {
            get
            {
                if (m_NativeSession != null)
                {
                    return m_NativeSession;
                }

                IntPtr sessionHandle = IntPtr.Zero;
                ExternApi.ArPresto_getSession(ref sessionHandle);

                IntPtr frameHandle = IntPtr.Zero;
                ExternApi.ArPresto_getFrame(ref frameHandle);

                if (sessionHandle == IntPtr.Zero || frameHandle == IntPtr.Zero)
                {
                    return null;
                }

                m_NativeSession = new NativeSession(sessionHandle, frameHandle);
                return m_NativeSession;
            }
        }

        public SessionStatus SessionStatus
        {
            get
            {
                ApiPrestoStatus prestoStatus = ApiPrestoStatus.Uninitialized;
                ExternApi.ArPresto_getStatus(ref prestoStatus);
                return prestoStatus.ToSessionStatus();
            }
        }

        public void CreateSession(ARCoreSession session)
        {
            session.StartCoroutine(InstantPreviewManager.InitializeIfNeeded());

            if (m_SessionComponent != null)
            {
                Debug.LogError("Multiple session components cannot exist in the scene. " +
                    "Destroying the newest.");
                GameObject.Destroy(session);
                return;
            }

            m_SessionComponent = session;
            EnableSession();
        }

        public void EnableSession()
        {
            if (m_SessionComponent == null)
            {
                return;
            }

            var config = m_SessionComponent.SessionConfig;
            if (config != null)
            {
                ExternApi.ArPresto_setConfiguration(new ApiPrestoConfig(config));
            }

            ExternApi.ArPresto_setEnabled(true);
        }

        public void DisableSession()
        {
            ExternApi.ArPresto_setEnabled(false);
        }

        public void DestroySession()
        {
            m_SessionComponent = null;
            m_NativeSession = null;
            ExternApi.ArPresto_reset();
        }

        public AsyncTask<ApkAvailabilityStatus> CheckApkAvailability()
        {
            Action<ApkAvailabilityStatus> onComplete;
            AsyncTask<ApkAvailabilityStatus> task =
                new AsyncTask<ApkAvailabilityStatus>(out onComplete);

            ExternApi.ArPresto_checkApkAvailability(m_CheckApkAvailabilityResultCallback,
                IntPtr.Zero);

            m_PendingAvailabilityCheckCallbacks.Add(onComplete);

            return task;
        }

        public AsyncTask<ApkInstallationStatus> RequestApkInstallation(bool userRequested)
        {
            Action<ApkInstallationStatus> onComplete;
            AsyncTask<ApkInstallationStatus> task =
                new AsyncTask<ApkInstallationStatus>(out onComplete);

            ExternApi.ArPresto_requestApkInstallation(userRequested,
                m_RequestApkInstallationResultCallback, IntPtr.Zero);

            m_PendingInstallationRequestCallbacks.Add(onComplete);

            return task;
        }

        [AOT.MonoPInvokeCallback(typeof(CheckApkAvailabilityResultCallback))]
        private static void OnCheckApkAvailabilityResultTrampoline(
            ApiAvailability status, IntPtr context)
        {
            Instance._OnCheckApkAvailabilityResult(status.ToApkAvailabilityStatus());
        }

        [AOT.MonoPInvokeCallback(typeof(RequestApkInstallationResultCallback))]
        private static void OnApkInstallationResultTrampoline(
            ApiApkInstallationStatus status, IntPtr context)
        {
            Instance._OnRequestApkInstallationResult(status.ToApkInstallationStatus());
        }

        [AOT.MonoPInvokeCallback(typeof(CameraPermissionRequestProvider))]
        private static void RequestCameraPermissionTrampoline(
            CameraPermissionsResultCallback onComplete, IntPtr context)
        {
            Instance._RequestCameraPermission(onComplete, context);
        }

        [AOT.MonoPInvokeCallback(typeof(EarlyUpdateCallback))]
        private static void EarlyUpdateTrampoline()
        {
            Instance._EarlyUpdate();
        }

        private void _Initialize()
        {
            m_EarlyUpdateCallback = new EarlyUpdateCallback(EarlyUpdateTrampoline);
            ExternApi.ArCoreUnity_setArPrestoInitialized(m_EarlyUpdateCallback);

            IntPtr javaVMHandle = IntPtr.Zero;
            IntPtr activityHandle = IntPtr.Zero;
            ExternApi.ArCoreUnity_getJniInfo(ref javaVMHandle, ref activityHandle);

            m_CheckApkAvailabilityResultCallback =
                new CheckApkAvailabilityResultCallback(OnCheckApkAvailabilityResultTrampoline);

            m_RequestApkInstallationResultCallback =
                new RequestApkInstallationResultCallback(OnApkInstallationResultTrampoline);

            m_RequestCameraPermissionCallback =
                new CameraPermissionRequestProvider(RequestCameraPermissionTrampoline);

            ExternApi.ArPresto_initialize(javaVMHandle, activityHandle,
                m_RequestCameraPermissionCallback);
        }

        private void _RequestCameraPermission(CameraPermissionsResultCallback onComplete,
            IntPtr context)
        {
            const string cameraPermissionName = "android.permission.CAMERA";
            AndroidPermissionsManager.RequestPermission(cameraPermissionName).ThenAction((grantResult) =>
            {
                onComplete(grantResult.IsAllGranted, context);
            });
        }

        private void _EarlyUpdate()
        {
            AsyncTask.OnUpdate();
            _UpdateTextureIfNeeded();

            if (m_SessionComponent != null)
            {
                var config = m_SessionComponent.SessionConfig;
                if (config != null)
                {
                    ExternApi.ArPresto_setConfiguration(new ApiPrestoConfig(config));
                }
            }

            if (m_NativeSession != null)
            {
                m_NativeSession.SessionApi.SetDisplayGeometry(
                    Screen.orientation, Screen.width, Screen.height);
                m_NativeSession.OnUpdate();
            }

            InstantPreviewManager.OnEarlyUpdate(m_SessionComponent);
        }

        private void _OnCheckApkAvailabilityResult(ApkAvailabilityStatus status)
        {
            foreach (var onComplete in m_PendingAvailabilityCheckCallbacks)
            {
                onComplete(status);
            }

            m_PendingAvailabilityCheckCallbacks.Clear();
        }

        private void _OnRequestApkInstallationResult(ApkInstallationStatus status)
        {
            foreach (var onComplete in m_PendingInstallationRequestCallbacks)
            {
                onComplete(status);
            }

            m_PendingInstallationRequestCallbacks.Clear();
        }

        private void _UpdateTextureIfNeeded()
        {
            // If running in editor, updates background texture from Instant Preview only.
            if (InstantPreviewManager.UpdateBackgroundTextureIfNeeded(ref m_BackgroundTexture))
            {
                return;
            }

            int backgroundTextureId = ExternApi.ArCoreUnity_getBackgroundTextureId();

            if (NativeSession == null)
            {
                // This prevents using a texture that has not been filled out by ARCore.
                return;
            }
            else if (backgroundTextureId == -1)
            {
                return;
            }
            else if (m_BackgroundTexture != null &&
                m_BackgroundTexture.GetNativeTexturePtr().ToInt32() == backgroundTextureId)
            {
                return;
            }
            else if (m_BackgroundTexture == null)
            {
                // The Unity-cached size and format of the texture (0x0, ARGB) is not the
                // actual format of the texture. This is okay because the texture is not
                // accessed by pixels, it is accessed with UV coordinates.
                m_BackgroundTexture = Texture2D.CreateExternalTexture(0, 0, TextureFormat.ARGB32, false,
                    false, new IntPtr(backgroundTextureId));
                return;
            }

            m_BackgroundTexture.UpdateExternalTexture(new IntPtr(backgroundTextureId));
        }

        private struct ExternApi
        {
            [DllImport(ApiConstants.ARCoreShimApi)]
            public static extern void ArCoreUnity_getJniInfo(ref IntPtr javaVM, ref IntPtr activity);

            [DllImport(ApiConstants.ARCoreShimApi)]
            public static extern void ArCoreUnity_setArPrestoInitialized(EarlyUpdateCallback onEarlyUpdate);

            [DllImport(ApiConstants.ARCoreShimApi)]
            public static extern int ArCoreUnity_getBackgroundTextureId();

            [DllImport(ApiConstants.ARCoreShimApi)]
            public static extern void ArPresto_initialize(IntPtr javaVM, IntPtr activity,
                CameraPermissionRequestProvider requestCameraPermission);

            [DllImport(ApiConstants.ARCoreShimApi)]
            public static extern void ArPresto_checkApkAvailability(
                CheckApkAvailabilityResultCallback onResult, IntPtr context);

            [DllImport(ApiConstants.ARCoreShimApi)]
            public static extern void ArPresto_requestApkInstallation(bool user_requested,
                RequestApkInstallationResultCallback onResult, IntPtr context);

            [DllImport(ApiConstants.ARCoreShimApi)]
            public static extern void ArPresto_getSession(ref IntPtr sessionHandle);

            [DllImport(ApiConstants.ARCoreShimApi)]
            public static extern void ArPresto_setConfiguration(ApiPrestoConfig config);

            [DllImport(ApiConstants.ARCoreShimApi)]
            public static extern void ArPresto_setEnabled(bool isEnabled);

            [DllImport(ApiConstants.ARCoreShimApi)]
            public static extern void ArPresto_getFrame(ref IntPtr frameHandle);

            [DllImport(ApiConstants.ARCoreShimApi)]
            public static extern void ArPresto_getStatus(ref ApiPrestoStatus prestoStatus);

            [DllImport(ApiConstants.ARCoreShimApi)]
            public static extern void ArPresto_reset();
        }
    }
}


text:
fileFormatVersion: 2
guid: 27167ddd916ef43bbaacd5878c2ae213
timeCreated: 1510945633
licenseType: Free
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: 864c8242be03c4aec8427b8a2286c601
timeCreated: 1517519681
licenseType: Pro
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: 84b5f07f2795d472e9c6e7bc3ed8bf35
timeCreated: 1502425714
licenseType: Free
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: ef23faba8749e46a5bd33fa98d0b4445
timeCreated: 1513114243
licenseType: Pro
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
//-----------------------------------------------------------------------
// <copyright file="ARDebug.cs" company="Google">
//
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System;
    using System.Diagnostics;
    using UnityEngine;

    /// <summary>
    /// A custom class similar to Unity's Debug.
    /// </summary>
    public class ARDebug
    {
        /// <summary>
        /// Logs an error with a stack trace.
        /// </summary>
        /// <param name="message">The error message.</param>
        public static void LogError(object message)
        {
            UnityEngine.Debug.LogErrorFormat(message + "\n{0}", new StackTrace(1));
        }

        /// <summary>
        /// Logs an error with a stack trace.
        /// </summary>
        /// <param name="format">The string format.</param>
        /// <param name="args">The output arguments.</param>
        public static void LogErrorFormat(string format, params object[] args)
        {
            object[] newArgs = new object[args.Length + 1];
            Array.Copy(args, newArgs, args.Length);
            newArgs[args.Length] = new StackTrace(1);
            UnityEngine.Debug.LogErrorFormat(format + "\n{" + args.Length + "}", newArgs);
        }
    }
}


text:
fileFormatVersion: 2
guid: ced698934296748419bf72ad4ac8a66b
timeCreated: 1502400449
licenseType: Free
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: 68605a05829544832b871afc8bf03168
timeCreated: 1518470830
licenseType: Pro
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
//-----------------------------------------------------------------------
// <copyright file="MarshalingHelper.cs" company="Google">
//
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using GoogleARCore;

    /// <summary>
    /// A helper class for mashalling data.
    /// </summary>
    public class MarshalingHelper
    {
        /// <summary>
        /// Adds the contents of an unmanaged struct array to a list.
        /// </summary>
        /// <param name="arrayPtr">A pointer to the unmanged array.</param>
        /// <param name="arrayLength">The length of the unmanaged array.</param>
        /// <param name="list">A list to append array elements to.</param>
        /// <typeparam name="T">The type contained by the unmanaged array.</typeparam>
        public static void AddUnmanagedStructArrayToList<T>(IntPtr arrayPtr, int arrayLength, List<T> list) where T : struct
        {
            if (arrayPtr == IntPtr.Zero || list == null)
            {
                return;
            }

            for (int i = 0; i < arrayLength; i++)
            {
                list.Add((T)Marshal.PtrToStructure(GetPtrToUnmanagedArrayElement<T>(arrayPtr, i), typeof(T)));
            }
        }

        /// <summary>
        /// Returns a pointer to an element within an unmanaged array.
        /// </summary>
        /// <returns>A pointer to the desired unmanaged array element.</returns>
        /// <param name="arrayPtr">A pointer to the start of the array.</param>
        /// <param name="arrayIndex">The index of the desired element pointer.</param>
        /// <typeparam name="T">The type contained by the unmanaged array.</typeparam>
        public static IntPtr GetPtrToUnmanagedArrayElement<T>(IntPtr arrayPtr, int arrayIndex) where T : struct
        {
            return new IntPtr(arrayPtr.ToInt64() + (Marshal.SizeOf(typeof(T)) * arrayIndex));
        }
    }
}


text:
fileFormatVersion: 2
guid: 1a1be6e2816d24b2ea1d6ec5f4be479d
timeCreated: 1510266639
licenseType: Free
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
//-----------------------------------------------------------------------
// <copyright file="ARCoreProjectSettings.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.IO;
    using UnityEngine;

    [Serializable]
    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
     Justification = "Internal")]
    public class ARCoreProjectSettings
    {
        public string Version;
        public bool IsARCoreRequired;
        public bool IsInstantPreviewEnabled;
        private const string k_VersionString = "V1.1.0";
        private const string k_ProjectSettingsPath = "ProjectSettings/ARCoreProjectSettings.json";

        static ARCoreProjectSettings()
        {
            if (Application.isEditor)
            {
                Instance = new ARCoreProjectSettings();
                Instance.Load();
            }
            else
            {
                Instance = null;
                Debug.LogError("Cannot access ARCoreProjectSettings outside of Unity Editor.");
            }
        }

        public static ARCoreProjectSettings Instance { get; private set; }

        public void Load()
        {
            Version = k_VersionString;
            IsARCoreRequired = true;
            IsInstantPreviewEnabled = true;

            if (File.Exists(k_ProjectSettingsPath))
            {
                ARCoreProjectSettings settings = JsonUtility.FromJson<ARCoreProjectSettings>(
                    File.ReadAllText(k_ProjectSettingsPath));
                Version = settings.Version;
                IsARCoreRequired = settings.IsARCoreRequired;
                IsInstantPreviewEnabled = settings.IsInstantPreviewEnabled;
            }

            // Upgrades settings from v1.0.0 to v1.1.0
            if (Version.Equals("V1.0.0"))
            {
                IsInstantPreviewEnabled = true;
                Version = k_VersionString;
            }
        }

        public void Save()
        {
            File.WriteAllText(k_ProjectSettingsPath, JsonUtility.ToJson(this));
        }
    }
}


text:
//-----------------------------------------------------------------------
// <copyright file="IntPtrEqualityComparer.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.InteropServices;
    using GoogleARCore;
    using UnityEngine;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
    Justification = "Internal")]
    public class IntPtrEqualityComparer : IEqualityComparer<IntPtr>
    {
        public bool Equals(IntPtr intPtr1, IntPtr intPtr2)
        {
            return intPtr1 == intPtr2;
        }

        public int GetHashCode(IntPtr intPtr)
        {
            return intPtr.GetHashCode();
        }
    }
}


text:
//-----------------------------------------------------------------------
// <copyright file="ConversionHelper.cs" company="Google">
//
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.InteropServices;
    using UnityEngine;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
     Justification = "Internal")]
    public class ConversionHelper
    {
        public static void UnityPoseToApiPose(Pose unityPose, out ApiPoseData apiPose)
        {
            Matrix4x4 glWorld_T_glLocal = Matrix4x4.TRS(unityPose.position, unityPose.rotation, Vector3.one);
            Matrix4x4 unityWorld_T_glWorld = Matrix4x4.Scale(new Vector3(1, 1, -1));
            Matrix4x4 unityWorld_T_unityLocal = unityWorld_T_glWorld * glWorld_T_glLocal * unityWorld_T_glWorld.inverse;

            Vector3 position = unityWorld_T_unityLocal.GetColumn(3);
            Quaternion rotation = Quaternion.LookRotation(unityWorld_T_unityLocal.GetColumn(2),
                unityWorld_T_unityLocal.GetColumn(1));

            apiPose.X = position.x;
            apiPose.Y = position.y;
            apiPose.Z = position.z;
            apiPose.Qx = rotation.x;
            apiPose.Qy = rotation.y;
            apiPose.Qz = rotation.z;
            apiPose.Qw = rotation.w;
        }

        public static void ApiPoseToUnityPose(ApiPoseData apiPose, out Pose unityPose)
        {
            Matrix4x4 glWorld_T_glLocal = Matrix4x4.TRS(new Vector3(apiPose.X, apiPose.Y, apiPose.Z),
                new Quaternion(apiPose.Qx, apiPose.Qy, apiPose.Qz, apiPose.Qw), Vector3.one);
            Matrix4x4 unityWorld_T_glWorld = Matrix4x4.Scale(new Vector3(1, 1, -1));
            Matrix4x4 unityWorld_T_unityLocal = unityWorld_T_glWorld * glWorld_T_glLocal * unityWorld_T_glWorld.inverse;

            Vector3 position = unityWorld_T_unityLocal.GetColumn(3);
            Quaternion rotation = Quaternion.LookRotation(unityWorld_T_unityLocal.GetColumn(2),
                unityWorld_T_unityLocal.GetColumn(1));

            unityPose = new Pose(position, rotation);
        }
    }
}


text:
fileFormatVersion: 2
guid: 09ecd63d3da8a410a90244cc9a8a049f
timeCreated: 1518228501
licenseType: Pro
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: 51b018421df5e4defbf0a70c95a5f749
timeCreated: 1518228237
licenseType: Pro
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
//-----------------------------------------------------------------------
// <copyright file="ARCoreRequiredMenuItem.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.IO;
    using UnityEditor;
    using UnityEngine;

    [InitializeOnLoad]
    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
     Justification = "Internal")]
    public static class ARCoreRequiredMenuItem
    {
        private const string k_MenuName = "Edit/Project Settings/ARCore/ARCore Required";
        private const int k_MenuPriority = 901;

        [MenuItem(k_MenuName, false, k_MenuPriority)]
        private static void ToggleARCoreRequiredMenuItem()
        {
            ARCoreProjectSettings.Instance.IsARCoreRequired = !ARCoreProjectSettings.Instance.IsARCoreRequired;
            ARCoreProjectSettings.Instance.Save();
        }

        [MenuItem(k_MenuName, true, k_MenuPriority)]
        private static bool ValidateARCoreRequiredMenuItem()
        {
            Menu.SetChecked(k_MenuName, ARCoreProjectSettings.Instance.IsARCoreRequired);
            return true;
        }
    }
}


text:
//-----------------------------------------------------------------------
// <copyright file="BuildHelper.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System.Diagnostics.CodeAnalysis;
    using UnityEditor;
    using UnityEditor.Build;
    using UnityEngine;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
     Justification = "Internal")]
    public class BuildHelper : IPreprocessBuild
    {
        [SuppressMessage("UnityRules.UnityStyleRules", "US1000:FieldsMustBeUpperCamelCase",
         Justification = "Overriden property.")]
        public int callbackOrder
        {
            get
            {
                return 0;
            }
        }

        public void OnPreprocessBuild(BuildTarget target, string path)
        {
            var isARCoreRequired = ARCoreProjectSettings.Instance.IsARCoreRequired;

            Debug.LogFormat("Building application with {0} ARCore support.",
                isARCoreRequired ? "REQUIRED" : "OPTIONAL");

            string[] requiredAarGuid = AssetDatabase.FindAssets("google_ar_required");
            string[] optionalAarGuid = AssetDatabase.FindAssets("google_ar_optional");
            if (requiredAarGuid.Length != 1 || optionalAarGuid.Length != 1)
            {
                throw new UnityEditor.Build.BuildFailedException(
                    "Not finding google_ar_required.aar and google_ar_optional.aar files needed for ARCore support. " +
                    "Were they moved from the ARCore SDK?");
            }

            PluginImporter arRequiredAAR = AssetImporter.GetAtPath(AssetDatabase.GUIDToAssetPath(requiredAarGuid[0])) as PluginImporter;
            PluginImporter arOptionalAAR = AssetImporter.GetAtPath(AssetDatabase.GUIDToAssetPath(optionalAarGuid[0])) as PluginImporter;

            if (arRequiredAAR == null || arOptionalAAR == null)
            {
                throw new UnityEditor.Build.BuildFailedException(
                    "Not finding google_ar_required.aar and google_ar_optional.aar files needed for ARCore support. " +
                    "Were they moved from the ARCore SDK?");
            }

            arRequiredAAR.SetCompatibleWithPlatform(BuildTarget.Android, isARCoreRequired);
            arOptionalAAR.SetCompatibleWithPlatform(BuildTarget.Android, !isARCoreRequired);
        }
    }
}


text:
fileFormatVersion: 2
guid: 20257a5d02b574ec8a372bb9e319d8b3
timeCreated: 1513294266
licenseType: Pro
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
//-----------------------------------------------------------------------
// <copyright file="ApiTrackingStateExtensions.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using GoogleARCore;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
    Justification = "Internal")]
    public static class ApiTrackingStateExtensions
    {
        public static TrackingState ToTrackingState(this ApiTrackingState apiTrackingState)
        {
            switch (apiTrackingState)
            {
                case ApiTrackingState.Tracking:
                    return TrackingState.Tracking;
                case ApiTrackingState.Paused:
                    return TrackingState.Paused;
                case ApiTrackingState.Stopped:
                    return TrackingState.Stopped;
                default:
                    return TrackingState.Stopped;
            }
        }
    }
}


text:
fileFormatVersion: 2
guid: 3a3a276a11cf042cc852e5b9f699553c
timeCreated: 1519866731
licenseType: Pro
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
//-----------------------------------------------------------------------
// <copyright file="ApiTrackedPointOrientationMode.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System.Diagnostics.CodeAnalysis;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
    Justification = "Internal")]
    public enum ApiTrackedPointOrientationMode
    {
        Identity = 0,
        SurfaceNormal = 1,
    }
}


text:
//-----------------------------------------------------------------------
// <copyright file="ApiApkInstallStatusExtensions.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using GoogleARCore;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
    Justification = "Internal")]
    public static class ApiApkInstallStatusExtensions
    {
        public static ApkInstallationStatus ToApkInstallationStatus(this ApiApkInstallationStatus apiStatus)
        {
            switch (apiStatus)
            {
                case ApiApkInstallationStatus.Uninitialized:
                    return ApkInstallationStatus.Uninitialized;
                case ApiApkInstallationStatus.Requested:
                    return ApkInstallationStatus.Requested;
                case ApiApkInstallationStatus.Success:
                    return ApkInstallationStatus.Success;
                case ApiApkInstallationStatus.Error:
                    return ApkInstallationStatus.Error;
                case ApiApkInstallationStatus.ErrorDeviceNotCompatible:
                    return ApkInstallationStatus.ErrorDeviceNotCompatible;
                case ApiApkInstallationStatus.ErrorUserDeclined:
                    return ApkInstallationStatus.ErrorUserDeclined;
                default:
                    UnityEngine.Debug.LogErrorFormat("Unexpected ApiApkInstallStatus status {0}", apiStatus);
                    return ApkInstallationStatus.Error;
            }
        }
    }
}


text:
fileFormatVersion: 2
guid: 0301646575b004ceca83800c3b3c9f06
timeCreated: 1509305507
licenseType: Free
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
//-----------------------------------------------------------------------
// <copyright file="LightEstimateApi.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.InteropServices;
    using GoogleARCore;
    using UnityEngine;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
    Justification = "Internal")]
    public class LightEstimateApi
    {
        private NativeSession m_NativeSession;

        public LightEstimateApi(NativeSession nativeSession)
        {
            m_NativeSession = nativeSession;
        }

        public IntPtr Create()
        {
            IntPtr lightEstimateHandle = IntPtr.Zero;
            ExternApi.ArLightEstimate_create(m_NativeSession.SessionHandle, ref lightEstimateHandle);
            return lightEstimateHandle;
        }

        public void Destroy(IntPtr lightEstimateHandle)
        {
            ExternApi.ArLightEstimate_destroy(lightEstimateHandle);
        }

        public LightEstimateState GetState(IntPtr lightEstimateHandle)
        {
            ApiLightEstimateState state = ApiLightEstimateState.NotValid;
            ExternApi.ArLightEstimate_getState(m_NativeSession.SessionHandle, lightEstimateHandle, ref state);
            return state.ToLightEstimateState();
        }

        public float GetPixelIntensity(IntPtr lightEstimateHandle)
        {
            float pixelIntensity = 0;
            ExternApi.ArLightEstimate_getPixelIntensity(m_NativeSession.SessionHandle,
                lightEstimateHandle, ref pixelIntensity);
            return pixelIntensity;
        }

        public Color GetColorCorrection(IntPtr lightEstimateHandle)
        {
            Color colorCorrection = Color.black;
            ExternApi.ArLightEstimate_getColorCorrection(m_NativeSession.SessionHandle,
                lightEstimateHandle, ref colorCorrection);
            return colorCorrection;
        }

        private struct ExternApi
        {
            [DllImport(ApiConstants.ARCoreNativeApi)]
            public static extern void ArLightEstimate_create(IntPtr sessionHandle,
                ref IntPtr lightEstimateHandle);

            [DllImport(ApiConstants.ARCoreNativeApi)]
            public static extern void ArLightEstimate_destroy(IntPtr lightEstimateHandle);

            [DllImport(ApiConstants.ARCoreNativeApi)]
            public static extern void ArLightEstimate_getState(IntPtr sessionHandle,
                IntPtr lightEstimateHandle, ref ApiLightEstimateState state);

            [DllImport(ApiConstants.ARCoreNativeApi)]
            public static extern void ArLightEstimate_getPixelIntensity(IntPtr sessionHandle,
                IntPtr lightEstimateHandle, ref float pixelIntensity);

            [DllImport(ApiConstants.ARCoreNativeApi)]
            public static extern void ArLightEstimate_getColorCorrection(IntPtr sessionHandle,
                IntPtr lightEstimateHandle, ref Color colorCorrection);
        }
    }
}


text:
fileFormatVersion: 2
guid: 7aa753c5e597b4841b03ea5f7f21326f
timeCreated: 1517874709
licenseType: Pro
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: 9732fd9cd933b45b9b101341baf74b73
timeCreated: 1510610167
licenseType: Pro
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
//-----------------------------------------------------------------------
// <copyright file="NativeSession.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.InteropServices;
    using GoogleARCore;
    using UnityEngine;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
    Justification = "Internal")]
    public class NativeSession
    {
        private IntPtr m_SessionHandle = IntPtr.Zero;

        private IntPtr m_FrameHandle = IntPtr.Zero;

        private IntPtr m_PointCloudHandle = IntPtr.Zero;

        private float m_LastReleasedPointcloudTimestamp = 0.0f;

        private TrackableManager m_TrackableManager = null;

        private Dictionary<IntPtr, int> m_AcquiredHandleCounts = new Dictionary<IntPtr, int>(
            new IntPtrEqualityComparer());

        public NativeSession(IntPtr sessionHandle, IntPtr frameHandle)
        {
            m_SessionHandle = sessionHandle;
            m_FrameHandle = frameHandle;
            m_TrackableManager = new TrackableManager(this);

            AnchorApi = new AnchorApi(this);
            CameraApi = new CameraApi(this);
            CameraMetadataApi = new CameraMetadataApi(this);
            FrameApi = new FrameApi(this);
            HitTestApi = new HitTestApi(this);
            ImageApi = new ImageApi(this);
            LightEstimateApi = new LightEstimateApi(this);
            PlaneApi = new PlaneApi(this);
            PointApi = new PointApi(this);
            PointCloudApi = new PointCloudApi(this);
            PoseApi = new PoseApi(this);
            SessionApi = new SessionApi(this);
            SessionConfigApi = new SessionConfigApi(this);
            TrackableApi = new TrackableApi(this);
            TrackableListApi = new TrackableListApi(this);
        }

        public IntPtr SessionHandle
        {
            get
            {
                return m_SessionHandle;
            }
        }

        public IntPtr FrameHandle
        {
            get
            {
                return m_FrameHandle;
            }
        }

        public IntPtr PointCloudHandle
        {
            get
            {
                return m_PointCloudHandle;
            }
        }

        public bool IsPointCloudNew
        {
            get
            {
                // TODO (b/73256094): Remove when fixed.
                if (LifecycleManager.Instance.SessionStatus != SessionStatus.Tracking)
                {
                    var previousLastTimestamp = m_LastReleasedPointcloudTimestamp;
                    m_LastReleasedPointcloudTimestamp = 0.0f;
                    return previousLastTimestamp != 0;
                }

                return PointCloudApi.GetTimestamp(PointCloudHandle) != m_LastReleasedPointcloudTimestamp;
            }
        }

        public AnchorApi AnchorApi { get; private set; }

        public CameraApi CameraApi { get; private set; }

        public CameraMetadataApi CameraMetadataApi { get; private set; }

        public FrameApi FrameApi { get; private set; }

        public HitTestApi HitTestApi { get; private set; }

        public ImageApi ImageApi { get; private set; }

        public LightEstimateApi LightEstimateApi { get; private set; }

        public PlaneApi PlaneApi { get; private set; }

        public PointApi PointApi { get; private set; }

        public PointCloudApi PointCloudApi { get; private set; }

        public PoseApi PoseApi { get; private set; }

        public SessionApi SessionApi { get; private set; }

        public SessionConfigApi SessionConfigApi { get; private set; }

        public TrackableApi TrackableApi { get; private set; }

        public TrackableListApi TrackableListApi { get; private set; }

        public void MarkHandleAcquired(IntPtr handle)
        {
            if (handle == IntPtr.Zero)
            {
                Debug.LogError("MarkHandleAcquired::Attempted to mark a null handle acquired.");
                return;
            }

            int acquireCount;
            m_AcquiredHandleCounts.TryGetValue(handle, out acquireCount);
            m_AcquiredHandleCounts[handle] = ++acquireCount;
        }

        public void MarkHandleReleased(IntPtr handle)
        {
            int acquireCount;
            if (m_AcquiredHandleCounts.TryGetValue(handle, out acquireCount))
            {
                if (--acquireCount > 0)
                {
                    m_AcquiredHandleCounts[handle] = acquireCount;
                }
                else
                {
                    m_AcquiredHandleCounts.Remove(handle);
                }
            }
        }

        public bool IsHandleAcquired(IntPtr handle)
        {
            int acquireCount;
            m_AcquiredHandleCounts.TryGetValue(handle, out acquireCount);
            return acquireCount > 0;
        }

        public Trackable TrackableFactory(IntPtr nativeHandle)
        {
            return m_TrackableManager.TrackableFactory(nativeHandle);
        }

        public void GetTrackables<T>(List<T> trackables, TrackableQueryFilter filter) where T : Trackable
        {
            m_TrackableManager.GetTrackables<T>(trackables, filter);
        }

        public void OnUpdate()
        {
            // After first frame, release previous frame's point cloud.
            if (m_PointCloudHandle != IntPtr.Zero)
            {
                m_LastReleasedPointcloudTimestamp = PointCloudApi.GetTimestamp(m_PointCloudHandle);
                PointCloudApi.Release(m_PointCloudHandle);
                m_PointCloudHandle = IntPtr.Zero;
            }

            // TODO (b/73256094): Remove when fixed.
            if (LifecycleManager.Instance.SessionStatus == SessionStatus.Tracking)
            {
                 FrameApi.TryAcquirePointCloudHandle(out m_PointCloudHandle);
            }
        }
    }
}


text:
fileFormatVersion: 2
guid: 3345208dea93f4ca6a361f8852a87704
timeCreated: 1517873495
licenseType: Pro
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: 226925a61d2444e8d9a12435697ce770
timeCreated: 1510543828
licenseType: Free
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: d8a0d471a5e1c486fb61de90a976a6d3
timeCreated: 1518035095
licenseType: Pro
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
//-----------------------------------------------------------------------
// <copyright file="ApiCameraMetadata.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules",
 "SA1649:FileHeaderFileNameDocumentationMustMatchTypeName", Justification = "Internal.")]

namespace GoogleARCoreInternal
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.InteropServices;
    using UnityEngine;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
    Justification = "Internal")]
    public enum NdkCameraMetadataType
    {
        Byte = 0,
        Int32 = 1,
        Float = 2,
        Int64 = 3,
        Double = 4,
        Rational = 5,
        NumTypes,
    }

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
    Justification = "Internal")]
    public enum NdkCameraStatus
    {
        Ok = 0,
        ErrorBase = -10000,
        ErrorUnknown = ErrorBase,
        ErrorInvalidParameter = ErrorBase - 1,
        ErrorMetadataNotFound = ErrorBase - 4,
    }

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
    Justification = "Internal")]
    [StructLayout(LayoutKind.Explicit)]
    public struct NdkCameraMetadata
    {
        [FieldOffset(0)]
        [MarshalAs(UnmanagedType.I4)]
        public int Tag;

        [FieldOffset(4)]
        [MarshalAs(UnmanagedType.I1)]
        public NdkCameraMetadataType Type;

        [FieldOffset(8)]
        [MarshalAs(UnmanagedType.I4)]
        public int Count;

        [FieldOffset(12)]
        public IntPtr Value;
    }
}


text:
//-----------------------------------------------------------------------
// <copyright file="ImageApi.cs" company="Google">
//
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCoreInternal
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.InteropServices;
    using GoogleARCore;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
    Justification = "Internal")]
    public class ImageApi
    {
        private NativeSession m_NativeSession;

        public ImageApi(NativeSession nativeSession)
        {
            m_NativeSession = nativeSession;
        }

        public void GetImageBuffer(IntPtr imageHandle, out int width, out int height, out IntPtr yPlane,
            out IntPtr uPlane, out IntPtr vPlane, out int yRowStride, out int uvPixelStride, out int uvRowStride)
        {
            IntPtr ndkImageHandle = IntPtr.Zero;
            ExternApi.ArImage_getNdkImage(imageHandle, ref ndkImageHandle);

            width = 0;
            ExternApi.AImage_getWidth(ndkImageHandle, ref width);

            height = 0;
            ExternApi.AImage_getHeight(ndkImageHandle, ref height);

            const int Y_PLANE = 0;
            const int U_PLANE = 1;
            const int V_PLANE = 2;
            int bufferLength = 0;

            yPlane = IntPtr.Zero;
            ExternApi.AImage_getPlaneData(ndkImageHandle, Y_PLANE, ref yPlane, ref bufferLength);

            uPlane = IntPtr.Zero;
            ExternApi.AImage_getPlaneData(ndkImageHandle, U_PLANE, ref uPlane, ref bufferLength);

            vPlane = IntPtr.Zero;
            ExternApi.AImage_getPlaneData(ndkImageHandle, V_PLANE, ref vPlane, ref bufferLength);

            yRowStride = 0;
            ExternApi.AImage_getPlaneRowStride(ndkImageHandle, Y_PLANE, ref yRowStride);

            uvPixelStride = 0;
            ExternApi.AImage_getPlanePixelStride(ndkImageHandle, U_PLANE, ref uvPixelStride);

            uvRowStride = 0;
            ExternApi.AImage_getPlaneRowStride(ndkImageHandle, U_PLANE, ref uvRowStride);
        }

        public void Release(IntPtr imageHandle)
        {
            m_NativeSession.MarkHandleReleased(imageHandle);
            ExternApi.ArImage_release(imageHandle);
        }

        private struct ExternApi
        {
            [DllImport(ApiConstants.ARCoreNativeApi)]
            public static extern void ArImage_getNdkImage(IntPtr imageHandle, ref IntPtr ndkImage);

            [DllImport(ApiConstants.ARCoreNativeApi)]
            public static extern void ArImage_release(IntPtr imageHandle);

            [DllImport(ApiConstants.MediaNdk)]
            public static extern int AImage_getWidth(IntPtr ndkImageHandle, ref int width);

            [DllImport(ApiConstants.MediaNdk)]
            public static extern int AImage_getHeight(IntPtr ndkImageHandle, ref int height);

            [DllImport(ApiConstants.MediaNdk)]
            public static extern int AImage_getPlaneData(IntPtr imageHandle, int planeIdx, ref IntPtr data,
                ref int dataLength);

            [DllImport(ApiConstants.MediaNdk)]
            public static extern int AImage_getPlanePixelStride(IntPtr imageHandle, int planeIdx, ref int pixelStride);

            [DllImport(ApiConstants.MediaNdk)]
            public static extern int AImage_getPlaneRowStride(IntPtr imageHandle, int planeIdx, ref int rowStride);
        }
    }
}