示例#1
0
        public void UpdateUnityConfigWithNDKConfig(IntPtr configHandle, ARConfigBase arconfig)
        {
            int ret = 0;

            NDKAPI.HwArConfig_getCameraLensFacing(m_ndkSession.SessionHandle, configHandle, ref ret);
            arconfig.SetCameraLensFacing((ARConfigCameraLensFacing)ret);
            AREnginesType aREnginesType = AREnginesSelector.Instance.GetCreatedEngine();

            ARDebug.LogInfo("UpdateUnityConfigWithNDKConfig GetARType size {0}", arconfig.GetARType());
            NDKAPI.HwArConfig_getLightEstimationMode(m_ndkSession.SessionHandle, configHandle, ref ret);
            arconfig.SetLightingMode((ARConfigLightingMode)ret);

            NDKAPI.HwArConfig_getPlaneFindingMode(m_ndkSession.SessionHandle, configHandle, ref ret);
            arconfig.SetPlaneFindingMode((ARConfigPlaneFindingMode)ret);

            NDKAPI.HwArConfig_getUpdateMode(m_ndkSession.SessionHandle, configHandle, ref ret);
            arconfig.SetUpdateMode((ARConfigUpdateMode)ret);

            //this interface only support by HUAWEI_AR_ENGINE
            if (AREnginesSelector.Instance.GetCreatedEngine() == AREnginesType.HUAWEI_AR_ENGINE)
            {
                NDKAPI.HwArConfig_getHandFindingMode(m_ndkSession.SessionHandle, configHandle, ref ret);
                arconfig.SetHandFindingMode((ARConfigHandFindingMode)ret);

                NDKAPI.HwArConfig_getPowerMode(m_ndkSession.SessionHandle, configHandle, ref ret);
                arconfig.SetPowerMode((ARConfigPowerMode)ret);

                ulong enableItem = 0;
                NDKAPI.HwArConfig_getEnableItem(m_ndkSession.SessionHandle, configHandle, ref enableItem);

                enableItem           = 0;
                arconfig.EnableDepth = Convert.ToBoolean(enableItem & ARConfigBase.EnableItem_Depth);
                arconfig.EnableMask  = Convert.ToBoolean(enableItem & ARConfigBase.EnableItem_Mask);
            }
        }
        public Dictionary <ARFace.BlendShapeLocation, float> GetBlendShapeData(IntPtr blendShapesHandle)
        {
            IntPtr dataHandle      = IntPtr.Zero;
            IntPtr shapeTypeHandle = IntPtr.Zero;
            int    dataSize        = 0;
            Dictionary <ARFace.BlendShapeLocation, float> ret = new Dictionary <ARFace.BlendShapeLocation, float>();

            NDKAPI.HwArFaceBlendShapes_getCount(m_ndkSession.SessionHandle, blendShapesHandle, ref dataSize);

            if (dataSize < 0 || dataSize > AdapterConstants.Enum_FaceBlendShapeLocation_MaxIntValue)
            {
                ARDebug.LogWarning("HwArFaceBlendShapes_getCount return value:{0}, while the legal max value is {1}",
                                   dataSize, AdapterConstants.Enum_FaceBlendShapeLocation_MaxIntValue);
                return(ret);
            }

            NDKAPI.HwArFaceBlendShapes_acquireTypes(m_ndkSession.SessionHandle, blendShapesHandle, ref shapeTypeHandle);
            NDKAPI.HwArFaceBlendShapes_acquireData(m_ndkSession.SessionHandle, blendShapesHandle, ref dataHandle);

            for (int i = 0; i < dataSize; i++)
            {
                int location = MarshalingHelper.GetValueOfUnmanagedArrayElement <int>(shapeTypeHandle, i);
                if (!ValueLegalityChecker.CheckInt("GetBlendShapeData", location,
                                                   AdapterConstants.Enum_FaceBlendShapeLocation_MinIntValue,
                                                   AdapterConstants.Enum_FaceBlendShapeLocation_MaxIntValue - 1))
                {
                    continue;
                }

                float val = MarshalingHelper.GetValueOfUnmanagedArrayElement <float>(dataHandle, i);

                ret.Add((ARFace.BlendShapeLocation)location, val);
            }
            return(ret);
        }
示例#3
0
        public void Stop()
        {
            NDKARStatus status = NDKAPI.HwArSession_stop(m_ndkSession.SessionHandle);

            ARDebug.LogInfo("native stop end with value:{0}", status);
            ARExceptionAdapter.ExtractException(status);
        }
示例#4
0
        public void SetDisplayGeometry(ScreenOrientation orientation, int width, int height)
        {
            const int androidRotation0   = 0;
            const int androidRotation90  = 1;
            const int androidRotation180 = 2;
            const int androidRotation270 = 3;

            int androidOrientation = 0;

            switch (orientation)
            {
            case ScreenOrientation.LandscapeLeft:
                androidOrientation = androidRotation90;
                break;

            case ScreenOrientation.LandscapeRight:
                androidOrientation = androidRotation270;
                break;

            case ScreenOrientation.Portrait:
                androidOrientation = androidRotation0;
                break;

            case ScreenOrientation.PortraitUpsideDown:
                androidOrientation = androidRotation180;
                break;
            }
            ARDebug.LogInfo("native set display geometry begin with android oritentation:{0}, width={1}, height={2}",
                            androidOrientation, width, height);
            NDKAPI.HwArSession_setDisplayGeometry(m_ndkSession.SessionHandle, androidOrientation, width, height);
        }
        public void GetValues(IntPtr cameraMetadataHandle,
                              ARCameraMetadataTag tag, List <ARCameraMetadataValue> resultList)
        {
            IntPtr ndkMetadataHandle = IntPtr.Zero;

            NDKAPI.HwArImageMetadata_getNdkCameraMetadata(m_ndkSession.SessionHandle,
                                                          cameraMetadataHandle, ref ndkMetadataHandle);

            resultList.Clear();
            NdkCameraMetadata entry  = new NdkCameraMetadata();
            NdkCameraStatus   status = NDKAPI.ACameraMetadata_getConstEntry(ndkMetadataHandle, tag, ref entry);

            if (status != NdkCameraStatus.Ok)
            {
                ARDebug.LogError("ACameraMetadata_getConstEntry error with native camera error code: {0}",
                                 status);
                return;
            }

            for (int i = 0; i < entry.Count; i++)
            {
                switch (entry.Type)
                {
                case NdkCameraMetadataType.Byte:
                    sbyte byteValue = MarshalingHelper.GetValueOfUnmanagedArrayElement <sbyte>(entry.Value, i);
                    resultList.Add(new ARCameraMetadataValue(byteValue));
                    break;

                case NdkCameraMetadataType.Int32:
                    int intValue = MarshalingHelper.GetValueOfUnmanagedArrayElement <int>(entry.Value, i);
                    resultList.Add(new ARCameraMetadataValue(intValue));
                    break;

                case NdkCameraMetadataType.Float:
                    float floatValue = MarshalingHelper.GetValueOfUnmanagedArrayElement <float>(entry.Value, i);
                    resultList.Add(new ARCameraMetadataValue(floatValue));
                    break;

                case NdkCameraMetadataType.Int64:
                    long longValue = MarshalingHelper.GetValueOfUnmanagedArrayElement <long>(entry.Value, i);
                    resultList.Add(new ARCameraMetadataValue(longValue));
                    break;

                case NdkCameraMetadataType.Double:
                    double doubleValue = MarshalingHelper.GetValueOfUnmanagedArrayElement <double>(entry.Value, i);
                    resultList.Add(new ARCameraMetadataValue(doubleValue));
                    break;

                case NdkCameraMetadataType.Rational:
                    ARCameraMetadataRational rationalValue = MarshalingHelper.GetValueOfUnmanagedArrayElement <
                        ARCameraMetadataRational>(entry.Value, i);
                    resultList.Add(new ARCameraMetadataValue(rationalValue));
                    break;

                default:
                    return;
                }
            }
        }
示例#6
0
        public void Destroy()
        {
            IntPtr sessionHandle = m_ndkSession.SessionHandle;

            ARDebug.LogInfo("native destroy session begin, handle =0x{0}", sessionHandle.ToString("x8"));
            NDKAPI.HwArSession_destroy(sessionHandle);
            ARDebug.LogInfo("native destroy session end");
        }
示例#7
0
        public string AcquireName(IntPtr AugImgHandle)
        {
            string ImgName = null;

            NDKAPI.HwArAugmentedImage_acquireName(m_ndkSession.SessionHandle, AugImgHandle, ref ImgName);
            ARDebug.LogInfo("AcquireName:{0}", ImgName);
            return(ImgName);
        }
        public void HitTestArea(float[] inPoints, List <ARHitResult> hitResultList)
        {
            hitResultList.Clear();

            if (inPoints == null || inPoints.Length == 0)
            {
                ARDebug.LogError("HitTestArea inPoints is empty");
                return;
            }

            float[] tmpIn = new float[inPoints.Length];
            inPoints.CopyTo(tmpIn, 0);
            GCHandle unmanagedInUVHandle = GCHandle.Alloc(tmpIn, GCHandleType.Pinned);

            IntPtr      hitResultListHandle = m_ndkSession.HitResultAdapter.CreateList();
            NDKARStatus status = NDKAPI.HwArFrame_hitTestArea(m_ndkSession.SessionHandle, m_ndkSession.FrameHandle,
                                                              unmanagedInUVHandle.AddrOfPinnedObject(), tmpIn.Length, hitResultListHandle);

            unmanagedInUVHandle.Free();

            if (status != NDKARStatus.HWAR_SUCCESS)
            {
                ARDebug.LogError("HitTestArea status is error:{}", status);
                return;
            }

            int cntOfResult = m_ndkSession.HitResultAdapter.GetListSize(hitResultListHandle);

            ARDebug.LogInfo("HitTestArea hit result count{0}", cntOfResult);
            for (int i = 0; i < cntOfResult; i++)
            {
                //todo refactor the following code when arplaneHitResult is removed
                IntPtr hitResultHandle = m_ndkSession.HitResultAdapter.AcquireListItem(hitResultListHandle, i);
                IntPtr trackableHandle = m_ndkSession.HitResultAdapter.GetTrackbaleHandle(hitResultHandle);
                ARDebug.LogInfo("HitTestArea hittype! {0}", m_ndkSession.TrackableAdapter.GetType(trackableHandle), i);
                switch (m_ndkSession.TrackableAdapter.GetType(trackableHandle))
                {
                case NDKARTrackableType.Plane:
                    hitResultList.Add(new ARPlaneHitResult(hitResultHandle, m_ndkSession));
                    break;

                case NDKARTrackableType.Point:
                    hitResultList.Add(new ARPointCloudHitResult(hitResultHandle, m_ndkSession, ARFrame.AcquirePointCloud()));
                    break;

                case NDKARTrackableType.Invalid:
                    break;

                case (NDKARTrackableType)0x41520105:
                    break;

                default:
                    hitResultList.Add(new ARHitResult(hitResultHandle, m_ndkSession));
                    break;
                }
            }
            m_ndkSession.HitResultAdapter.DestroyList(hitResultListHandle);
        }
示例#9
0
 public void Config(ARConfigBase config)
 {
     if (ARSessionStatus.PAUSED != Instance.SessionStatus &&
         ARSessionStatus.INIT != Instance.SessionStatus)
     {
         ARDebug.LogWarning("config when session is not init or paused, ignore it");
     }
     Instance.m_ndkSession.SessionAdapter.Config(config);
 }
示例#10
0
 public ARAnchor AddAnchor(Pose pose)
 {
     if (ARSessionStatus.RUNNING != Instance.SessionStatus)
     {
         ARDebug.LogWarning("add anchor when session is not running, ignore it");
         throw new ARNotYetAvailableException();
     }
     return(Instance.m_ndkSession.SessionAdapter.CreateAnchor(pose));
 }
 public static bool CheckInt(string methodName, int toCheckValue, int minValue, int maxValue = Int32.MaxValue)
 {
     if (toCheckValue < minValue || toCheckValue > maxValue)
     {
         ARDebug.LogWarning("{0}: value is {1}, while legal min value is {2}, max value is {3}",
                            methodName, toCheckValue, minValue, maxValue);
         return(false);
     }
     return(true);
 }
示例#12
0
 public void Pause()
 {
     if (ARSessionStatus.STOPPED == SessionStatus)
     {
         ARDebug.LogWarning("session is stopped when pause, ignore it");
         return;
     }
     m_ndkSession.SessionAdapter.Pause();
     SessionStatus = ARSessionStatus.PAUSED;
 }
示例#13
0
 public void SetDisplayGeometry(int width, int height)
 {
     if (ARSessionStatus.STOPPED == SessionStatus)
     {
         ARDebug.LogWarning("Session is stopped when SetDisplayGeometry, ignore it");
         return;
     }
     m_ndkSession.SessionAdapter.SetDisplayGeometry(Screen.orientation, Screen.width, Screen.height);
     DisplayGeometrySet = true;
 }
示例#14
0
        public ARTrackable ARTrackableFactory(IntPtr nativeHandle, bool isCreate = false)
        {
            if (nativeHandle == IntPtr.Zero)
            {
                return(null);
            }
            ARTrackable result;

            if (m_trackableDict.TryGetValue(nativeHandle, out result))
            {
                m_ndkSession.TrackableAdapter.Release(nativeHandle);
                return(result);
            }
            if (isCreate)
            {
                NDKARTrackableType ndkTrackableType = m_ndkSession.TrackableAdapter.GetType(nativeHandle);
                ARDebug.LogInfo("trackable type {0}", ndkTrackableType.ToString());
                switch (ndkTrackableType)
                {
                case NDKARTrackableType.Plane:
                    result = new ARPlane(nativeHandle, m_ndkSession);
                    break;

                case NDKARTrackableType.Point:
                    result = new ARPoint(nativeHandle, m_ndkSession);
                    break;

                case NDKARTrackableType.Body:
                    result = new ARBody(nativeHandle, m_ndkSession);
                    break;

                case NDKARTrackableType.Hand:
                    result = new ARHand(nativeHandle, m_ndkSession);
                    break;

                case NDKARTrackableType.Face:
                    result = new ARFace(nativeHandle, m_ndkSession);
                    break;

                case NDKARTrackableType.AugmentedImage:
                    result = new ARAugmentedImage(nativeHandle, m_ndkSession);
                    break;

                //todo add more trackable
                default:
                    m_ndkSession.TrackableAdapter.Release(nativeHandle);
                    throw new NotImplementedException("ARTrackableFactory: no constructor for requested type");
                }

                m_trackableDict.Add(nativeHandle, result);
                return(result);
            }
            return(null);
        }
示例#15
0
 public void Update()
 {
     if (SessionStatus != ARSessionStatus.RESUMED &&
         SessionStatus != ARSessionStatus.RUNNING)
     {
         ARDebug.LogWarning("update when state is not resumed or running, ignore it");
         return;
     }
     m_ndkSession.SessionAdapter.Update();
     SessionStatus = ARSessionStatus.RUNNING;
 }
        public IntPtr CreateAugImgDatabaseFromBytes(byte[] databaseBytes)
        {
            IntPtr      databaseHandle = IntPtr.Zero;
            var         bytesHandle    = GCHandle.Alloc(databaseBytes, GCHandleType.Pinned);
            NDKARStatus status         = NDKAPI.HwArAugmentedImageDatabase_deserialize(m_ndkSession.SessionHandle,
                                                                                       bytesHandle.AddrOfPinnedObject(), databaseBytes.Length, ref databaseHandle);

            ARDebug.LogInfo("native AddImageWithPhysicalSize end with status={0}", status);
            ARExceptionAdapter.ExtractException(status);
            bytesHandle.Free();
            return(databaseHandle);
        }
        public ARCameraIntrinsics GetImageIntrinsics(IntPtr cameraHandle)
        {
            ARDebug.LogInfo("ARCamera adapter get image intrinsics start");
            IntPtr arCameraIntrinsicsHandle = IntPtr.Zero;

            NDKAPI.HwArCameraIntrinsics_create(m_ndkSession.SessionHandle, ref arCameraIntrinsicsHandle);
            NDKAPI.HwArCamera_getImageIntrinsics(m_ndkSession.SessionHandle, cameraHandle, arCameraIntrinsicsHandle);
            ARCameraIntrinsics imageIntrinsics = GetARCameraIntrinsicsFromeHandle(arCameraIntrinsicsHandle);

            NDKAPI.HwArCameraIntrinsics_destroy(m_ndkSession.SessionHandle, arCameraIntrinsicsHandle);
            ARDebug.LogInfo("ARCamera adapter get image intrinsics end");
            return(imageIntrinsics);
        }
示例#18
0
        public void Config(ARConfigBase unityConfig)
        {
            //ARDebug.LogInfo("native config begin" + unityConfig.ToString());
            IntPtr configHandle = m_ndkSession.ConfigBaseAdapter.Create();

            m_ndkSession.ConfigBaseAdapter.UpdateNDKConfigWithUnityConfig(configHandle, unityConfig);
            NDKARStatus status = NDKAPI.HwArSession_configure(m_ndkSession.SessionHandle, configHandle);

            ARDebug.LogInfo("native config end with value:{0}", status);
            m_ndkSession.ConfigBaseAdapter.UpdateUnityConfigWithNDKConfig(configHandle, unityConfig);
            m_ndkSession.ConfigBaseAdapter.Destroy(configHandle);
            ARExceptionAdapter.ExtractException(status);
        }
        public ARWorldMappingState GetMappingState()
        {
            int ret = (int)ARWorldMappingState.NOT_AVAILABLE;

            NDKAPI.HwArFrame_getMappingState(m_ndkSession.SessionHandle, m_ndkSession.FrameHandle, ref ret);
            ARDebug.LogError("NDK world map status " + ret);
            if (!ValueLegalityChecker.CheckInt("GetMappingState", ret,
                                               AdapterConstants.Enum_ARWorldMappingState_MinIntValue,
                                               AdapterConstants.Enum_ARWorldMappingState_MaxIntValue))
            {
                return(ARWorldMappingState.NOT_AVAILABLE);
            }
            return((ARWorldMappingState)ret);
        }
示例#20
0
        public void GetTrackables <T>(List <T> trackables, ARTrackableQueryFilter filter) where T : ARTrackable
        {
            if (m_lastUpdateFrame < Time.frameCount)
            {
                // Get trackables updated this frame.
                m_ndkSession.FrameAdapter.GetUpdatedTrackables(m_updatedTrackables);

                // Get all the trackables in the session.
                m_ndkSession.SessionAdapter.GetAllTrackables(m_allTrackables);

                ARDebug.LogInfo("m_updatedTrackables {0} m_allTrackables {1}", m_updatedTrackables.Count, m_allTrackables.Count);
                // Find trackables that are not in the hashset (new).
                m_newTrackables.Clear();
                for (int i = 0; i < m_allTrackables.Count; i++)
                {
                    ARTrackable 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 == ARTrackableQueryFilter.ALL)
            {
                for (int i = 0; i < m_allTrackables.Count; i++)
                {
                    _SafeAdd <T>(m_allTrackables[i], trackables);
                }
            }
            else if (filter == ARTrackableQueryFilter.NEW)
            {
                for (int i = 0; i < m_newTrackables.Count; i++)
                {
                    _SafeAdd <T>(m_newTrackables[i], trackables);
                }
            }
            else if (filter == ARTrackableQueryFilter.UPDATED)
            {
                for (int i = 0; i < m_updatedTrackables.Count; i++)
                {
                    _SafeAdd <T>(m_updatedTrackables[i], trackables);
                }
            }
        }
示例#21
0
        public IntPtr Create()
        {
            IntPtr sessionHandle = IntPtr.Zero;

            ARDebug.LogInfo("native create seesion begin");

            IntPtr      jEnv     = ARUnityHelper.Instance.GetJEnv();
            IntPtr      activity = ARUnityHelper.Instance.GetActivityHandle();
            NDKARStatus status   = NDKAPI.HwArSession_create(jEnv, activity, ref sessionHandle);

            ARDebug.LogInfo("native create seesion returns status {0}", status);
            ARExceptionAdapter.ExtractException(status);
            return(sessionHandle);
        }
示例#22
0
 public void Resume()
 {
     if (ARSessionStatus.STOPPED == SessionStatus)
     {
         ARDebug.LogWarning("Session is stopped when resume, ignore it");
         return;
     }
     if (!AndroidPermissionsRequest.IsPermissionGranted("android.permission.CAMERA"))
     {
         throw new ARCameraPermissionDeniedException();
     }
     m_ndkSession.SessionAdapter.Resume();
     SessionStatus = ARSessionStatus.RESUMED;
 }
示例#23
0
        public ARAnchor CreateAnchor(Pose pose)
        {
            IntPtr poseHandle   = m_ndkSession.PoseAdapter.Create(pose);
            IntPtr anchorHandle = IntPtr.Zero;

            ARDebug.LogInfo("native acquire anchor begin with pose:{0}", pose.ToString());
            NDKARStatus status = NDKAPI.HwArSession_acquireNewAnchor(m_ndkSession.SessionHandle,
                                                                     poseHandle, ref anchorHandle);

            ARDebug.LogInfo("native acquire anchor end with status={0}", status);
            m_ndkSession.PoseAdapter.Destroy(poseHandle);
            ARExceptionAdapter.ExtractException(status);
            var anchor = m_ndkSession.AnchorManager.ARAnchorFactory(anchorHandle, true);

            return(anchor);
        }
        public void HitTest(float pixelX, float pixelY, List <ARHitResult> hitResultList)
        {
            hitResultList.Clear();

            IntPtr hitResultListHandle = m_ndkSession.HitResultAdapter.CreateList();

            NDKAPI.HwArFrame_hitTest(m_ndkSession.SessionHandle, m_ndkSession.FrameHandle, pixelX, pixelY, hitResultListHandle);
            int cntOfResult = m_ndkSession.HitResultAdapter.GetListSize(hitResultListHandle);

            ARDebug.LogInfo("HitTest hitresult {0}", cntOfResult);
            for (int i = 0; i < cntOfResult; i++)
            {
                //todo refactor the following code when arplaneHitResult is removed
                IntPtr hitResultHandle = m_ndkSession.HitResultAdapter.AcquireListItem(hitResultListHandle, i);
                IntPtr trackableHandle = m_ndkSession.HitResultAdapter.GetTrackbaleHandle(hitResultHandle);
                ARDebug.LogInfo("HitTest hittype! {0}", m_ndkSession.TrackableAdapter.GetType(trackableHandle), i);
                switch (m_ndkSession.TrackableAdapter.GetType(trackableHandle))
                {
                case NDKARTrackableType.Plane:
                    hitResultList.Add(new ARPlaneHitResult(hitResultHandle, m_ndkSession));
                    break;

                case NDKARTrackableType.Point:
                    hitResultList.Add(new ARPointCloudHitResult(hitResultHandle, m_ndkSession, ARFrame.AcquirePointCloud()));
                    break;

                case NDKARTrackableType.Invalid:
                    break;

                case (NDKARTrackableType)0x41520105:
                    break;

                default:
                    hitResultList.Add(new ARHitResult(hitResultHandle, m_ndkSession));
                    break;
                }
            }
            m_ndkSession.HitResultAdapter.DestroyList(hitResultListHandle);
        }
示例#25
0
        public void GetPlanePolygon(IntPtr planeHandle, List <Vector3> points)
        {
            points.Clear();
            int pointCount = 0;

            NDKAPI.HwArPlane_getPolygonSize(m_ndkSession.SessionHandle, planeHandle, ref pointCount);
            if (pointCount < 1)
            {
                return;
            }
            else if (pointCount > m_maxPolygonSize)
            {
                ARDebug.LogInfo("GetPlanePolygon: plane polygon size exceeds.");
                pointCount = m_maxPolygonSize;
            }
            NDKAPI.HwArPlane_getPolygon(m_ndkSession.SessionHandle, planeHandle, m_tmpPointsHandle.AddrOfPinnedObject());

            for (int i = pointCount - 2; i >= 0; i -= 2)
            {
                var point = new Vector3(m_tmpPoints[i], 0, -m_tmpPoints[i + 1]);
                points.Add(point);
            }
        }
        public void GetAllCameraMetadataTags(IntPtr cameraMetadataHandle, List <ARCameraMetadataTag> resultList)
        {
            IntPtr metadataHandle = IntPtr.Zero;

            NDKAPI.HwArImageMetadata_getNdkCameraMetadata(m_ndkSession.SessionHandle,
                                                          cameraMetadataHandle, ref metadataHandle);

            IntPtr          tagsHandle = IntPtr.Zero;
            int             tagsCount  = 0;
            NdkCameraStatus status     = NDKAPI.ACameraMetadata_getAllTags(metadataHandle, ref tagsCount, ref tagsHandle);

            if (status != NdkCameraStatus.Ok)
            {
                ARDebug.LogError("ACameraMetadata_getAllTags error with native camera error code: {0}",
                                 status);
                return;
            }

            for (int i = 0; i < tagsCount; i++)
            {
                resultList.Add((ARCameraMetadataTag)MarshalingHelper.GetValueOfUnmanagedArrayElement <int>(tagsHandle, i));
            }
        }
 public void Destroy(IntPtr dataBaseHandle)
 {
     ARDebug.LogInfo("native destroy session begin, handle =0x{0}", dataBaseHandle.ToString("x8"));
     NDKAPI.HwArAugmentedImageDatabase_destroy(dataBaseHandle);
     ARDebug.LogInfo("native destroy session end");
 }