public void Release(IntPtr imageHandle) { ExternApi.ArImage_release(imageHandle); }
/// <summary> /// Creates the texture reader instance. /// </summary> /// <param name="format">Format of the output image pixel. Can be either eImageFormat_RGBA /// or eImageFormat_I8.</param> /// <param name="width">Width of the output image, in pixels.</param> /// <param name="height">Height of the output image, in pixels.</param> /// <param name="keepAspectRatio">Indicate whether or not to keep aspect ratio. If true, the /// output image may be cropped if the image aspect ratio is different from the texture /// aspect ratio. If false, the output image covers the entire texture scope and no cropping /// is applied.</param> public void Create(ImageFormatType format, int width, int height, bool keepAspectRatio) { ExternApi.TextureReader_create((int)format, width, height, keepAspectRatio); }
private bool HitResultListGetItemAt(IntPtr hitResultListHandle, int index, out TrackableHit outTrackableHit) { outTrackableHit = new TrackableHit(); // Query the hit result. IntPtr hitResultHandle = IntPtr.Zero; ExternApi.ArHitResult_create(m_NativeSession.SessionHandle, ref hitResultHandle); ExternApi.ArHitResultList_getItem(m_NativeSession.SessionHandle, hitResultListHandle, index, hitResultHandle); if (hitResultHandle == IntPtr.Zero) { ExternApi.ArHitResult_destroy(hitResultHandle); return(false); } // Query the pose from hit result. IntPtr poseHandle = m_NativeSession.PoseApi.Create(); ExternApi.ArHitResult_getHitPose(m_NativeSession.SessionHandle, hitResultHandle, poseHandle); Pose hitPose = m_NativeSession.PoseApi.ExtractPoseValue(poseHandle); // Query the distance from hit result. float hitDistance = 0.0f; ExternApi.ArHitResult_getDistance(m_NativeSession.SessionHandle, hitResultHandle, ref hitDistance); // Query the trackable from hit result. IntPtr trackableHandle = IntPtr.Zero; ExternApi.ArHitResult_acquireTrackable(m_NativeSession.SessionHandle, hitResultHandle, ref trackableHandle); Trackable trackable = m_NativeSession.TrackableFactory(trackableHandle); m_NativeSession.TrackableApi.Release(trackableHandle); // Calculate trackable hit flags. TrackableHitFlags flag = TrackableHitFlags.None; if (trackable == null) { Debug.Log("Could not create trackable from hit result."); m_NativeSession.PoseApi.Destroy(poseHandle); return(false); } else if (trackable is DetectedPlane) { if (m_NativeSession.PlaneApi.IsPoseInPolygon(trackableHandle, poseHandle)) { flag |= TrackableHitFlags.PlaneWithinPolygon; } if (m_NativeSession.PlaneApi.IsPoseInExtents(trackableHandle, poseHandle)) { flag |= TrackableHitFlags.PlaneWithinBounds; } flag |= TrackableHitFlags.PlaneWithinInfinity; } else if (trackable is FeaturePoint) { var point = trackable as FeaturePoint; flag |= TrackableHitFlags.FeaturePoint; if (point.OrientationMode == FeaturePointOrientationMode.SurfaceNormal) { flag |= TrackableHitFlags.FeaturePointWithSurfaceNormal; } } else { m_NativeSession.PoseApi.Destroy(poseHandle); return(false); } outTrackableHit = new TrackableHit(hitPose, hitDistance, flag, trackable); m_NativeSession.PoseApi.Destroy(poseHandle); return(true); }
public void DestroyList(IntPtr anchorListHandle) { ExternApi.ArAnchorList_destroy(anchorListHandle); }
/// <summary> /// Acquires the output image pixels from a previous reading request. /// </summary> /// <param name="bufferIndex">The buffer index required by previous call to /// SubmitFrame().</param> /// <param name="bufferSize">The size of the output image pixel buffer, in bytes.</param> /// <returns>The pointer to the raw buffer of the output image. null if fails.</returns> public IntPtr AcquireFrame(int bufferIndex, ref int bufferSize) { IntPtr pixelBuffer = ExternApi.TextureReader_acquireFrame(bufferIndex, ref bufferSize); return(pixelBuffer); }
public Cubemap GetReflectionCubemap(IntPtr sessionHandle, IntPtr lightEstimateHandle) { int size = 0; bool usingGammaWorkflow = QualitySettings.activeColorSpace == ColorSpace.Gamma; #if UNITY_2017_2_OR_NEWER // Cubemap.CreateExternalTexture only exists in Unity 2017 above. int textureId = 0; ApiTextureDataType dataType = SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3 ? ApiTextureDataType.Half : ApiTextureDataType.Byte; TextureFormat format = dataType == ApiTextureDataType.Half ? TextureFormat.RGBAHalf : TextureFormat.RGBA32; if (!_pluginInitialized) { ExternApi.ARCoreRenderingUtils_SetTextureDataType(dataType, true); ExternApi.ARCoreRenderingUtils_SetActiveColorSpace(usingGammaWorkflow); _pluginInitialized = true; } ExternApi.ARCoreRenderingUtils_GetCubemapTexture(ref textureId, ref size); if (textureId != 0 && (_hdrCubemap == null || textureId != _cubemapTextureId)) { _hdrCubemap = Cubemap.CreateExternalTexture(size, format, true, new IntPtr(textureId)); _cubemapTextureId = textureId; } long timestamp = GetTimestamp(sessionHandle, lightEstimateHandle); if (_cubemapTimestamp != timestamp) { ExternApi.ARCoreRenderingUtils_SetARCoreLightEstimation(sessionHandle, lightEstimateHandle); _cubemapTimestamp = timestamp; } // Issue plugin event to update cubemap texture. GL.IssuePluginEvent(ExternApi.ARCoreRenderingUtils_GetRenderEventFunc(), (int)ApiRenderEvent.UpdateCubemapTexture); #else // Gets raw color data from native plugin then update cubemap textures by // Cubemap.SetPixel(). // Note, no GL texture will be created in this scenario. if (!_pluginInitialized) { ExternApi.ARCoreRenderingUtils_SetTextureDataType( ApiTextureDataType.Float, false); ExternApi.ARCoreRenderingUtils_SetActiveColorSpace(usingGammaWorkflow); _pluginInitialized = true; } ExternApi.ARCoreRenderingUtils_GetCubemapTexture(ref _cubemapTextureId, ref size); if (size > 0) { if (_hdrCubemap == null) { _hdrCubemap = new Cubemap(size, TextureFormat.RGBAHalf, true); } if (_tempCubemapFacePixels.Length != size) { Array.Resize(ref _tempCubemapFacePixels, size * size); } } long timestamp = GetTimestamp(sessionHandle, lightEstimateHandle); if (_cubemapTimestamp != timestamp) { ExternApi.ARCoreRenderingUtils_SetARCoreLightEstimation(sessionHandle, lightEstimateHandle); _cubemapTimestamp = timestamp; if (_hdrCubemap != null) { for (int i = 0; i < 6; i++) { ExternApi.ARCoreRenderingUtils_GetCubemapRawColors(i, _tempCubemapFacePixels); _hdrCubemap.SetPixels(_tempCubemapFacePixels, CubemapFace.PositiveX + i); } // This operation is very expensive, only update cubemap texture when // the light estimate is updated in this frame. _hdrCubemap.Apply(); } } #endif return(_hdrCubemap); }
public static void Detach( IntPtr sessionHandle, IntPtr anchorHandle) { ExternApi.ArAnchor_detach(sessionHandle, anchorHandle); }
public void Destory(IntPtr recordingConfigHandle) { ExternApi.ArRecordingConfig_destroy(recordingConfigHandle); }
public void Destroy(IntPtr cameraConfigListHandle) { ExternApi.ArCameraConfigFilter_destroy(cameraConfigListHandle); }
private void _OnEarlyUpdate() { // Update session activity before EarlyUpdate. if (m_HaveDisableToEnableTransition) { _SetSessionEnabled(false); // Refresh SessionStatus after first _SetSessionEnabled() to catch any changes to // the SessionStatus that may affect the subsequent _SetSessionEnabled(). // This fixes an issue where the session does not get re-enabled properly when an // unsupported configuration is fixed, and the ARCoreSession component's enabled // state is toggled in the same frame; ApiPrestoStatus refreshPrestoStatus = ApiPrestoStatus.Uninitialized; ExternApi.ArPresto_getStatus(ref refreshPrestoStatus); SessionStatus = refreshPrestoStatus.ToSessionStatus(); _SetSessionEnabled(true); m_HaveDisableToEnableTransition = false; // Avoid firing session enable event twice. if (m_DesiredSessionState.HasValue && m_DesiredSessionState.Value) { m_DesiredSessionState = null; } } if (m_DesiredSessionState.HasValue) { _SetSessionEnabled(m_DesiredSessionState.Value); m_DesiredSessionState = null; } // Perform updates before calling ArPresto_update. if (SessionComponent != null) { IntPtr previousSession = IntPtr.Zero; ExternApi.ArPresto_getSession(ref previousSession); if (UpdateSessionFeatures != null) { UpdateSessionFeatures(); } _SetCameraDirection(SessionComponent.DeviceCameraDirection); IntPtr currentSession = IntPtr.Zero; ExternApi.ArPresto_getSession(ref currentSession); // Fire the session enabled event when the underlying session has been changed // due to session feature update(camera direction etc). if (previousSession != currentSession) { _FireOnSessionSetEnabled(false); _FireOnSessionSetEnabled(true); } _SetConfiguration(SessionComponent.SessionConfig); } _UpdateDisplayGeometry(); // Update ArPresto and potentially ArCore. ExternApi.ArPresto_update(); SessionStatus previousSessionStatus = SessionStatus; // Get state information from ARPresto. ApiPrestoStatus prestoStatus = ApiPrestoStatus.Uninitialized; ExternApi.ArPresto_getStatus(ref prestoStatus); SessionStatus = prestoStatus.ToSessionStatus(); LostTrackingReason = LostTrackingReason.None; if (NativeSession != null && SessionStatus == SessionStatus.LostTracking) { var cameraHandle = NativeSession.FrameApi.AcquireCamera(); LostTrackingReason = NativeSession.CameraApi.GetLostTrackingReason(cameraHandle); NativeSession.CameraApi.Release(cameraHandle); } // If the current status is an error, check if the SessionStatus error state changed. if (SessionStatus.IsError() && previousSessionStatus.IsError() != SessionStatus.IsError()) { // Disable internal session bits so we properly pause the session due to error. _FireOnSessionSetEnabled(false); } // Get the current session from presto and note if it has changed. IntPtr sessionHandle = IntPtr.Zero; ExternApi.ArPresto_getSession(ref sessionHandle); IsSessionChangedThisFrame = m_CachedSessionHandle != sessionHandle; m_CachedSessionHandle = sessionHandle; ExternApi.ArPresto_getFrame(ref m_CachedFrameHandle); // Update the native session with the newest frame. if (NativeSession != null) { NativeSession.OnUpdate(m_CachedFrameHandle); } _UpdateTextureIfNeeded(); if (EarlyUpdate != null) { EarlyUpdate(); } }
public void Release(IntPtr cameraHandle) { ExternApi.ArCamera_release(cameraHandle); }
public void ResetSession() { _FireOnSessionSetEnabled(false); _Initialize(); ExternApi.ArPresto_reset(); }
public void GetItemAt(IntPtr cameraConfigListHandle, int index, IntPtr cameraConfigHandle) { ExternApi.ArCameraConfigList_getItem(m_NativeSession.SessionHandle, cameraConfigListHandle, index, cameraConfigHandle); }
private void _OnEarlyUpdate() { _SetCameraTextureName(); // Update session activity before EarlyUpdate. if (m_HaveDisableToEnableTransition) { _SetSessionEnabled(false); _SetSessionEnabled(true); m_HaveDisableToEnableTransition = false; // Avoid firing session enable event twice. if (m_DesiredSessionState.HasValue && m_DesiredSessionState.Value) { m_DesiredSessionState = null; } } if (m_DesiredSessionState.HasValue) { _SetSessionEnabled(m_DesiredSessionState.Value); m_DesiredSessionState = null; } // Perform updates before calling ArPresto_update. if (SessionComponent != null) { IntPtr previousSession = IntPtr.Zero; ExternApi.ArPresto_getSession(ref previousSession); if (UpdateSessionFeatures != null) { UpdateSessionFeatures(); } _SetCameraDirection(SessionComponent.DeviceCameraDirection); IntPtr currentSession = IntPtr.Zero; ExternApi.ArPresto_getSession(ref currentSession); // Fire the session enabled event when the underlying session has been changed // due to session feature update(camera direction etc). if (previousSession != currentSession) { _FireOnSessionSetEnabled(false); _FireOnSessionSetEnabled(true); } // Validate and convert the SessionConfig to a Instant Preview supported config by // logging and disabling limited supported features. if (InstantPreviewManager.IsProvidingPlatform && SessionComponent.SessionConfig != null && !InstantPreviewManager.ValidateSessionConfig(SessionComponent.SessionConfig)) { // A new SessionConfig object will be created based on the original // SessionConfig with all limited support features disabled. SessionComponent.SessionConfig = InstantPreviewManager.GenerateInstantPreviewSupportedConfig( SessionComponent.SessionConfig); } _UpdateConfiguration(SessionComponent.SessionConfig); } _UpdateDisplayGeometry(); // Update ArPresto and potentially ArCore. ExternApi.ArPresto_update(); if (SystemInfo.graphicsMultiThreaded && !InstantPreviewManager.IsProvidingPlatform) { // Synchronize render thread with update call. ExternApi.ARCoreRenderingUtils_CreatePostUpdateFence(); } SessionStatus previousSessionStatus = SessionStatus; // Get state information from ARPresto. ApiPrestoStatus prestoStatus = ApiPrestoStatus.Uninitialized; ExternApi.ArPresto_getStatus(ref prestoStatus); SessionStatus = prestoStatus.ToSessionStatus(); LostTrackingReason = LostTrackingReason.None; if (NativeSession != null && SessionStatus == SessionStatus.LostTracking) { var cameraHandle = NativeSession.FrameApi.AcquireCamera(); LostTrackingReason = NativeSession.CameraApi.GetLostTrackingReason(cameraHandle); NativeSession.CameraApi.Release(cameraHandle); } // If the current status is an error, check if the SessionStatus error state changed. if (SessionStatus.IsError() && previousSessionStatus.IsError() != SessionStatus.IsError()) { // Disable internal session bits so we properly pause the session due to error. _FireOnSessionSetEnabled(false); m_DisabledSessionOnErrorState = true; } else if (SessionStatus.IsValid() && m_DisabledSessionOnErrorState) { if (SessionComponent.enabled) { _FireOnSessionSetEnabled(true); } m_DisabledSessionOnErrorState = false; } // Get the current session from presto and note if it has changed. IntPtr sessionHandle = IntPtr.Zero; ExternApi.ArPresto_getSession(ref sessionHandle); IsSessionChangedThisFrame = m_CachedSessionHandle != sessionHandle; m_CachedSessionHandle = sessionHandle; ExternApi.ArPresto_getFrame(ref m_CachedFrameHandle); // Update the native session with the newest frame. if (NativeSession != null) { NativeSession.OnUpdate(m_CachedFrameHandle); } _UpdateTextureIfNeeded(); if (EarlyUpdate != null) { EarlyUpdate(); } }
public ApiArStatus ResolveCloudAnchor(String cloudAnchorId, out IntPtr cloudAnchorHandle) { cloudAnchorHandle = IntPtr.Zero; return(ExternApi.ArSession_resolveAndAcquireNewCloudAnchor(m_NativeSession.SessionHandle, cloudAnchorId, ref cloudAnchorHandle)); }
public void Destroy(IntPtr nativePose) { ExternApi.ArPose_destroy(nativePose); }
public void ReportEngineType() { ExternApi.ArSession_reportEngineType(m_NativeSession.SessionHandle, "Unity", Application.unityVersion); }
public ApiArStatus SetCameraConfig(IntPtr cameraConfigHandle) { return(ExternApi.ArSession_setCameraConfig( m_NativeSession.SessionHandle, cameraConfigHandle)); }
public void Destroy(IntPtr lightEstimateHandle) { ExternApi.ArLightEstimate_destroy(lightEstimateHandle); }
public static bool HitTest(Vector2 screenPosition, out TrackableHit outTrackableHit) { outTrackableHit = new TrackableHit(); // The native session provides the session and frame handles. var nativeSession = LifecycleManager.Instance.NativeSession; if (nativeSession == null) { Debug.LogError("NativeSession is null."); return(false); } IntPtr hitResultListHandle = IntPtr.Zero; ExternApi.ArHitResultList_create( nativeSession.SessionHandle, ref hitResultListHandle); ExternApi.ArFrame_depthHitTest( nativeSession.SessionHandle, nativeSession.FrameHandle, screenPosition.x, screenPosition.y, hitResultListHandle); int hitListSize = 0; ExternApi.ArHitResultList_getSize( nativeSession.SessionHandle, hitResultListHandle, ref hitListSize); if (hitListSize == 0) { return(false); } // Depth hit test only returns one hit test per pixel referenced. const int itemIndex = 0; // Query the hit result. IntPtr hitResultHandle = IntPtr.Zero; ExternApi.ArHitResult_create( nativeSession.SessionHandle, ref hitResultHandle); ExternApi.ArHitResultList_getItem( nativeSession.SessionHandle, hitResultListHandle, itemIndex, hitResultHandle); if (hitResultHandle == IntPtr.Zero) { ExternApi.ArHitResult_destroy(hitResultHandle); return(false); } // Query the pose from hit result. IntPtr poseHandle = nativeSession.PoseApi.Create(); ExternApi.ArHitResult_getHitPose( nativeSession.SessionHandle, hitResultHandle, poseHandle); Pose hitPose = nativeSession.PoseApi.ExtractPoseValue(poseHandle); // Query the distance from hit result. float hitDistance = 0.0f; ExternApi.ArHitResult_getDistance( nativeSession.SessionHandle, hitResultHandle, ref hitDistance); // Query the trackable from hit result. IntPtr trackableHandle = IntPtr.Zero; ExternApi.ArHitResult_acquireTrackable( nativeSession.SessionHandle, hitResultHandle, ref trackableHandle); Trackable trackable = nativeSession.TrackableFactory(trackableHandle); nativeSession.TrackableApi.Release(trackableHandle); // Calculate trackable hit flags. TrackableHitFlags flag = TrackableHitFlags.None; if (trackable == null) { Debug.Log("Could not create trackable from hit result."); nativeSession.PoseApi.Destroy(poseHandle); return(false); } else if (trackable is FeaturePoint) { var point = trackable as FeaturePoint; flag |= TrackableHitFlags.FeaturePoint; if (point.OrientationMode == FeaturePointOrientationMode.SurfaceNormal) { flag |= TrackableHitFlags.FeaturePointWithSurfaceNormal; } } outTrackableHit = new TrackableHit(hitPose, hitDistance, flag, trackable); nativeSession.PoseApi.Destroy(poseHandle); ExternApi.ArHitResultList_destroy(hitResultListHandle); return(true); }
public void Release(IntPtr pointCloudHandle) { ExternApi.ArPointCloud_release(pointCloudHandle); }
/// <summary> /// Queries the image delegate for a texture data and updates the given array and texture. /// </summary> /// <typeparam name="T">Can be either short (for depth) or byte (for confidence).</typeparam> /// <param name="texture">The texture to update with new data.</param> /// <param name="dataArray">The CPU array to update with new data.</param> /// <param name="acquireImageDelegate">The function to call to obtain data.</param> private void _UpdateTexture <T>( ref Texture2D texture, ref T[] dataArray, AcquireDepthImageDelegate acquireImageDelegate) { // The native session provides the session and frame handles. var nativeSession = LifecycleManager.Instance.NativeSession; if (nativeSession == null) { Debug.LogError("NativeSession is null."); return; } // Get the current depth image. IntPtr imageHandle = IntPtr.Zero; if (acquireImageDelegate( nativeSession.SessionHandle, nativeSession.FrameHandle, ref imageHandle) == false) { return; } int previousDepthWidth = m_DepthWidth; int previousDepthHeight = m_DepthHeight; // Gets the size of the depth data. ExternApi.ArImage_getWidth( nativeSession.SessionHandle, imageHandle, out m_DepthWidth); ExternApi.ArImage_getHeight(nativeSession.SessionHandle, imageHandle, out m_DepthHeight); if (previousDepthWidth != m_DepthWidth || previousDepthHeight != m_DepthHeight) { _InitializeCameraIntrinsics(); } // Accesses the depth image surface data. IntPtr planeDoublePtr = IntPtr.Zero; int planeSize = 0; ExternApi.ArImage_getPlaneData( nativeSession.SessionHandle, imageHandle, /*plane_index*/ 0, ref planeDoublePtr, ref planeSize); IntPtr planeDataPtr = new IntPtr(planeDoublePtr.ToInt64()); int pixelStride = 0; ExternApi.ArImage_getPlanePixelStride(nativeSession.SessionHandle, imageHandle, /*plane_index*/ 0, ref pixelStride); // Resizes the CPU data array based on the updated size. if (dataArray.Length != planeSize / pixelStride) { Array.Resize(ref dataArray, planeSize / pixelStride); } // Copies the depth data into the provided CPU data array. if (pixelStride == 1) { // Pixel stride is 2, used for confidence data. Marshal.Copy(planeDataPtr, dataArray as byte[], 0, dataArray.Length); } else { // Pixel stride is 2, used for depth data. Marshal.Copy(planeDataPtr, dataArray as short[], 0, dataArray.Length); } // Resize the depth texture if needed. if (m_DepthWidth != texture.width || m_DepthHeight != texture.height) { if (pixelStride == 1) { texture.Resize(m_DepthWidth, m_DepthHeight, TextureFormat.R8, false); } else { texture.Resize(m_DepthWidth, m_DepthHeight, TextureFormat.RGB565, false); } } // Copies the raw depth data to the texture. texture.LoadRawTextureData(planeDataPtr, planeSize); texture.Apply(); // Releases the depth image. LifecycleManager.Instance.NativeSession.ImageApi.Release(imageHandle); return; }
public static void Release(IntPtr anchorHandle) { ExternApi.ArAnchor_release(anchorHandle); }
private void _UpdateDepthArray <T>( ref T[] dataArray, AcquireDepthImageDelegate acquireImageDelegate) { // The native session provides the session and frame handles. var nativeSession = LifecycleManager.Instance.NativeSession; if (nativeSession == null) { Debug.LogError("NativeSession is null."); return; } // Gets the current depth image. IntPtr imageHandle = IntPtr.Zero; if (acquireImageDelegate( nativeSession.SessionHandle, nativeSession.FrameHandle, ref imageHandle) == false) { return; } // Gets the size of the depth data. int width = 0; int height = 0; ExternApi.ArImage_getWidth( nativeSession.SessionHandle, imageHandle, out width); ExternApi.ArImage_getHeight(nativeSession.SessionHandle, imageHandle, out height); // Accesses the depth image surface data. IntPtr planeDoublePtr = IntPtr.Zero; int planeSize = 0; ExternApi.ArImage_getPlaneData( nativeSession.SessionHandle, imageHandle, /*plane_index=*/ 0, ref planeDoublePtr, ref planeSize); IntPtr planeDataPtr = new IntPtr(planeDoublePtr.ToInt32()); int depthPixelCount = width * height; // Resizes the CPU depth array based on the updated size. if (dataArray.Length != depthPixelCount) { Array.Resize(ref dataArray, depthPixelCount); } int pixelStride = 0; ExternApi.ArImage_getPlanePixelStride(nativeSession.SessionHandle, imageHandle, /*plane_index*/ 0, ref pixelStride); // Copies the depth data into the provided CPU depth array. if (pixelStride == 1) { Marshal.Copy(planeDataPtr, dataArray as byte[], 0, dataArray.Length); } else { Marshal.Copy(planeDataPtr, dataArray as short[], 0, dataArray.Length); } // Releases the depth image. LifecycleManager.Instance.NativeSession.ImageApi.Release(imageHandle); return; }
/// <summary> /// Releases a previously used frame buffer. /// </summary> /// <param name="bufferIndex">The buffer index required by previous call to /// SubmitFrame().</param> public void ReleaseFrame(int bufferIndex) { ExternApi.TextureReader_releaseFrame(bufferIndex); }
public void SetReferenceImageDatabase(IntPtr configHandle, IntPtr imageDatabase) { ExternApi.arConfigSetReferenceImageDatabase(m_NativeSession.SessionHandle, configHandle, imageDatabase); }
/// <summary> /// Destroys the texture reader instance and release internal resources. /// </summary> public void Destroy() { ExternApi.TextureReader_destroy(); }
public void Destroy(IntPtr configHandle) { ExternApi.arConfigDestroy(configHandle); }
public void Release(IntPtr frameHandle) { ExternApi.ArFrame_release(frameHandle); }
public void GetPlaneData(IntPtr imageHandle, int planeIndex, ref IntPtr surfaceData, ref int dataLength) { ExternApi.ArImage_getPlaneData(_nativeSession.SessionHandle, imageHandle, planeIndex, ref surfaceData, ref dataLength); }