//-------------------------------------------------------------------------------------------------------------------
    // Constructor


    /// <summary> Extract right-handed coordinate system data from the SenseGlove DLL and convert it into Unity values. </summary>
    /// <param name="data"></param>
    /// <param name="packets"></param>
    /// <param name="totalCSteps"></param>
    /// <param name="currCStep"></param>
    public SenseGlove_Data(SenseGloveCs.GloveData data)
    {
        if (data != null)
        {
            this.dataLoaded = data.dataLoaded;
            this.gloveSide  = SenseGlove_Data.GetSide(data.kinematics.isRight);

            this.deviceID        = data.deviceID;
            this.firmwareVersion = data.firmwareVersion;
            this.gloveVersion    = data.deviceVersion;

            this.gloveValues      = data.gloveValues;
            this.imuValues        = data.imuValues;
            this.imuCalibration   = data.imuCalibration;
            this.packetsPerSecond = data.samplesPerSec;
            this.numberOfSensors  = data.numberOfSensors;

            this.calibrationStep       = data.currentCalStep;
            this.totalCalibrationSteps = data.totalCalSteps;

            this.absoluteCalibratedWrist = SenseGlove_Util.ToUnityQuaternion(data.wrist.QcalibratedAbs);
            this.absoluteWrist           = SenseGlove_Util.ToUnityQuaternion(data.wrist.QwristAbs);
            this.relativeWrist           = SenseGlove_Util.ToUnityQuaternion(data.wrist.Qrelative);

            this.commonOriginPos = SenseGlove_Util.ToUnityPosition(data.kinematics.gloveRelPos);
            this.commonOriginRot = SenseGlove_Util.ToUnityQuaternion(data.kinematics.gloveRelRot);

            SenseGlove_Data.GetChainVariables(ref data.kinematics.gloveLinks, ref this.glovePositions,
                                              ref this.gloveAngles, ref this.gloveRotations, ref this.gloveLengths);

            SenseGlove_Data.GetChainVariables(ref data.kinematics.fingers, ref this.handPositions,
                                              ref this.handAngles, ref this.handRotations, ref this.handLengths);
        }
    }
    //-------------------------------------------------------------------------------------------------------------------
    // Constructor

    /// <summary> Create an instance of SenseGlove_Data with default values. </summary>
    protected SenseGlove_Data()
    {
        SetEmpty();
        this.dataLoaded      = false;
        this.deviceID        = "N\\A";
        this.firmwareVersion = -1.0f;
        this.gloveSide       = GloveSide.Unknown;
        this.gloveValues     = new float[0][] { };
        this.gloveVersion    = "N\\A";
        this.numberOfSensors = 0;
    }
        /// <summary> Retrieves an interpolator from the disk. Returns true if one is actually available. </summary>
        /// <param name="side"></param>
        /// <returns></returns>
        public static bool LoadInterpolation(SenseGloveCs.DeviceType type, GloveSide side, out string output)
        {
            string FN = GetFilename(type, side);

            string[] contents;
            if (Util.FileIO.ReadTxtFile(calibrDir + FN, out contents) && contents.Length > 0)
            {
                output = contents[0];
                return(output != null);
            }
            output = null;
            return(false);
        }
    /// <summary> Extract right-handed coordinate system data from the SenseGlove DLL and convert it into Unity values. </summary>
    /// <param name="data"></param>
    /// <param name="packets"></param>
    /// <param name="totalCSteps"></param>
    /// <param name="currCStep"></param>
    public SenseGlove_Data(SenseGloveCs.GloveData data)
    {
        if (data != null)
        {
            this.gloveSide = SenseGlove_Data.GetSide(data.kinematics.isRight);

            this.deviceID        = data.deviceID;
            this.firmwareVersion = data.firmwareVersion;
            this.gloveVersion    = data.deviceVersion;

            this.packetsPerSecond = data.samplesPerSec;

            this.commonOriginPos = SenseGlove_Util.ToUnityPosition(data.kinematics.gloveRelPos);
            this.commonOriginRot = SenseGlove_Util.ToUnityQuaternion(data.kinematics.gloveRelRot);

            this.UpdateVariables(data);
        }
    }
    //-------------------------------------------------------------------------------------------------------------------
    // Constructor

    /// <summary> Create an instance of SenseGlove_Data with default values. </summary>
    private SenseGlove_Data()
    {
        Vector3[]   zero      = new Vector3[] { Vector3.zero, Vector3.zero, Vector3.zero };
        Vector3[][] multiZero = new Vector3[5][] { zero, zero, zero, zero, zero };

        Quaternion[]   ident      = new Quaternion[] { Quaternion.identity, Quaternion.identity, Quaternion.identity };
        Quaternion[][] multiIdent = new Quaternion[5][] { ident, ident, ident, ident, ident };

        this.absoluteCalibratedWrist = Quaternion.identity;
        this.absoluteWrist           = Quaternion.identity;
        this.calibrationStep         = -1;
        this.commonOriginPos         = Vector3.zero;
        this.commonOriginRot         = Quaternion.identity;
        this.dataLoaded      = false;
        this.deviceID        = "N\\A";
        this.firmwareVersion = -1.0f;
        this.gloveAngles     = multiZero;
        this.gloveLengths    = multiZero;
        this.glovePositions  = multiZero;
        this.gloveRotations  = multiIdent;
        this.gloveSide       = GloveSide.Unknown;
        this.gloveValues     = new float[0][] { };
        this.gloveVersion    = "N\\A";
        this.handAngles      = multiZero;
        this.handLengths     = multiZero;
        this.handPositions   = multiZero;
        this.handRotations   = multiIdent;
        this.imuCalibration  = new int[4] {
            -1, -1, -1, -1
        };
        this.imuValues             = new float[] { 0, 0, 0, 1 };
        this.numberOfSensors       = 0;
        this.packetsPerSecond      = 0;
        this.relativeWrist         = Quaternion.identity;
        this.totalCalibrationSteps = 0;
    }
 /// <summary> Stores a serialized value of an interpolator onto a disk. </summary>
 /// <param name="interpolator"></param>
 /// <param name="side"></param>
 public static void StoreInterpolation(string interpolator, SenseGloveCs.DeviceType type, GloveSide side)
 {
     if (interpolator != null)
     {
         string   FN       = GetFilename(type, side);
         string[] contents = new string[] { interpolator };
         Util.FileIO.SaveTxtFile(calibrDir, FN, contents, false);
     }
 }
        /// <summary> Generate a new filename for this calibration profile. </summary>
        /// <param name="side"></param>
        /// <returns></returns>
        private static string GetFilename(SenseGloveCs.DeviceType type, GloveSide side)
        {
            string subFile = "SG-"; //dynamically generated later, when more devices become available.

            return(subFile + (side == GloveSide.LeftHand ? "L" : "R") + ".txt");
        }