/****************************************************************************** * Copyright (C) Ultraleap, Inc. 2011-2023. * * * * Use subject to the terms of the Apache License 2.0 available at * * http://www.apache.org/licenses/LICENSE-2.0, or another agreement * * between Ultraleap and you, your company or other organization. * ******************************************************************************/ using System; namespace Leap { /// /// The DistortionData class contains the distortion map for correcting the /// lens distortion of an image. /// /// The distortion data is an array containing a 64x64 grid of floating point pairs. /// The distortion map for both sides of an image pair are stacked in /// the Data array -- the left map first, followed by the right map. /// /// @since 3.0 /// public class DistortionData { private float[] _flippedData; private float[] _originalData; /// /// Constructs an uninitialized distortion object. /// @since 3.0 /// public DistortionData() { } /// /// @since 3.0 /// public DistortionData(UInt64 version, float width, float height, float[] data) { Version = version; Width = width; Height = height; Data = data; } /// /// An identifier assigned to the distortion map. /// /// When the distortion map changes -- either because the devices flips the images /// to automatically orient the hands or because a different device is plugged in, /// the version number of the distortion data changes. /// /// Note that the version always increases. If the images change orientation and then /// return to their original orientation, a new version number is assigned. Thus /// the version number can be used to detect when the data has changed, but not /// to uniquely identify the data. /// @since 3.0 /// public UInt64 Version { get; set; } /// /// The width of the distortion map. /// /// Currently always 64. Note that there are two floating point values for every point in the map. /// @since 3.0 /// public float Width { get; set; } /// /// The height of the distortion map. /// /// Currently always 64. /// @since 3.0 /// public float Height { get; set; } /// /// The original distortion data, as provided by the service /// /// @since 3.0 /// public float[] Data { get { return _originalData; } set { _originalData = value; // Note, the contents of the array are normally copied into the buffer by a marshall operation, // so the flipped data needs to be updated explicitly, not when the _orginalData member is set } } /// /// Returns the distortion data, adjusted so that a location in the distortion map texture now refers to the /// same region of the texture containing the IR image - e.g. the bottom left of the distortion texture /// maps to bottom left of the IR image /// /// @since 3.0 /// public float[] FlippedData { get { return _flippedData; } } /// /// Reports whether the distortion data is internally consistent. /// @since 3.0 /// public bool IsValid { get { if (Data != null && Width == LeapInternal.LeapC.DistortionSize && Height == LeapInternal.LeapC.DistortionSize && Data.Length == Width * Height * 2) return true; return false; } } internal void OnDataChanged() { UpdateFlippedData(); } private void UpdateFlippedData() { if (_originalData == null) { return; } // This is called normally once a session, so allocation is fine float[] flipped = new float[LeapInternal.LeapC.DistortionSize * LeapInternal.LeapC.DistortionSize * 2]; for (int x = 0; x < LeapInternal.LeapC.DistortionSize; x++) { for (int y = 0; y < LeapInternal.LeapC.DistortionSize; y++) { // We change the data so that the *mapped* Y value is inverted flipped[((x + y * LeapInternal.LeapC.DistortionSize) * 2)] = _originalData[((x + y * LeapInternal.LeapC.DistortionSize) * 2)]; flipped[((x + y * LeapInternal.LeapC.DistortionSize) * 2) + 1] = (float)1.0 - _originalData[((x + y * LeapInternal.LeapC.DistortionSize) * 2) + 1]; } } _flippedData = flipped; } } }