/// <summary> /// Get the most recent light estimate. /// </summary> /// <returns></returns> public LightEstimate GetLatestLightEstimate() { // Maintain frame consistency. if (Time.frameCount == m_latestLightEstimateFrame) { return(m_latestLightEstimate); } m_latestLightEstimateFrame = Time.frameCount; UnityTango.NativeImage nativeImage = new UnityTango.NativeImage(); if (!UnityTango.Device.TryAcquireLatestImageBuffer(ref nativeImage)) { Debug.LogError("Unable to acquire image buffer."); return(m_latestLightEstimate); } // The Y plane is always the first one. var yPlaneInfo = nativeImage.planeInfos[0]; IntPtr yPlaneStart = new IntPtr(nativeImage.planeData.ToInt64() + yPlaneInfo.offset); float intensity; ApiServiceErrorStatus status = TangoClientApi.TangoService_getPixelIntensity( yPlaneStart, (int)nativeImage.width, (int)nativeImage.height, nativeImage.planeInfos[0].rowStride, out intensity); if (status != ApiServiceErrorStatus.Success) { Debug.LogErrorFormat("Call to getPixelIntensity failed: {0}.", status); return(m_latestLightEstimate); } m_latestLightEstimate = new LightEstimate(intensity); UnityTango.Device.ReleaseImageBuffer(nativeImage); return(m_latestLightEstimate); }
public override bool TryGetCameraImage(ref CameraImage cameraImage) { ARCoreNative.NativeImage nativeImage = new ARCoreNative.NativeImage(); if (ARCoreNative.Device.TryAcquireLatestImageBuffer(ref nativeImage)) { cameraImage.width = (int)nativeImage.width; cameraImage.height = (int)nativeImage.height; var planeInfos = nativeImage.planeInfos; // The Y plane is always the first one. var yOffset = planeInfos[0].offset; var numYBytes = planeInfos[0].size; IntPtr yPlaneStart = new IntPtr(nativeImage.planeData.ToInt64() + yOffset); if (cameraImage.y == null || cameraImage.y.Length != numYBytes) { cameraImage.y = new byte[numYBytes]; } Marshal.Copy(yPlaneStart, cameraImage.y, 0, (int)numYBytes); // UV planes are not deterministic, but we want all the data in one go // so the offset will be the min of the two planes. int uvOffset = Mathf.Min( (int)nativeImage.planeInfos[1].offset, (int)nativeImage.planeInfos[2].offset); // Find the end of the uv plane data int uvDataEnd = 0; for (int i = 1; i < planeInfos.Count; ++i) { uvDataEnd = Mathf.Max(uvDataEnd, (int)planeInfos[i].offset + planeInfos[i].size); } // Finally, compute the number of bytes by subtracting the end from the beginning var numUVBytes = uvDataEnd - uvOffset; IntPtr uvPlaneStart = new IntPtr(nativeImage.planeData.ToInt64() + uvOffset); if (cameraImage.uv == null || cameraImage.uv.Length != numUVBytes) { cameraImage.uv = new byte[numUVBytes]; } Marshal.Copy(uvPlaneStart, cameraImage.uv, 0, (int)numUVBytes); ARCoreNative.Device.ReleaseImageBuffer(nativeImage); // The data is usually provided as VU rather than UV, // so we need to swap the bytes. // There's no way to know this currently, but it's always // been this way on every device so far. for (int i = 1; i < numUVBytes; i += 2) { var b = cameraImage.uv[i - 1]; cameraImage.uv[i - 1] = cameraImage.uv[i]; cameraImage.uv[i] = b; } return(true); } return(false); }